java_security
Differences
This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revision | |||
| java_security [2007/04/10 10:39] – slonopotamus | java_security [2019/06/12 16:08] (current) – external edit 127.0.0.1 | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| + | [[start|На главную]] | ||
| + | ====== Реализация системы безопасности в Java ====== | ||
| + | Всё нижеописанное исходит из предположения что в Sun хорошо подумали когда | ||
| + | проектировали пермишены, | ||
| + | |||
| + | |||
| + | ===== О чём это вообще ===== | ||
| + | В типичном веб-приложении далеко не каждый пользователь может менять любые данные. У кого-то есть доступ только на чтение, | ||
| + | ==== Что защищать ==== | ||
| + | Любые данные. | ||
| + | ==== Зачем защищать ==== | ||
| + | Чтобы разделять, | ||
| + | |||
| + | |||
| + | ===== Аутентификация ===== | ||
| + | ==== Несортированный трэш ==== | ||
| + | <code java> | ||
| + | // | ||
| + | Policy.setPolicy(new Policy() | ||
| + | { | ||
| + | public boolean implies(final ProtectionDomain domain, final Permission permission) | ||
| + | { | ||
| + | for (final Principal principal : domain.getPrincipals()) { | ||
| + | if (principal instanceof MyPrincipal) { | ||
| + | // | ||
| + | } | ||
| + | } | ||
| + | return false; | ||
| + | } | ||
| + | }); | ||
| + | // | ||
| + | final Configuration orig = Configuration.getConfiguration(); | ||
| + | Configuration.setConfiguration(new Configuration() | ||
| + | { | ||
| + | public AppConfigurationEntry[] getAppConfigurationEntry(final String name) | ||
| + | { | ||
| + | return (name.equals(" | ||
| + | new AppConfigurationEntry[]{ | ||
| + | new AppConfigurationEntry( | ||
| + | " | ||
| + | AppConfigurationEntry.LoginModuleControlFlag.REQUISITE, | ||
| + | Collections.< | ||
| + | ) | ||
| + | } : orig.getAppConfigurationEntry(name); | ||
| + | } | ||
| + | |||
| + | public void refresh() | ||
| + | { | ||
| + | orig.refresh(); | ||
| + | } | ||
| + | }); | ||
| + | System.setSecurityManager(new SecurityManager()); | ||
| + | // | ||
| + | final String name = " | ||
| + | final String password = " | ||
| + | final LoginContext ctx = new LoginContext(" | ||
| + | { | ||
| + | public void handle(final Callback[] callbacks) throws IOException, | ||
| + | { | ||
| + | for (final Callback cb : callbacks) | ||
| + | { | ||
| + | if (cb instanceof NameCallback) | ||
| + | { | ||
| + | ((NameCallback) cb).setName(name); | ||
| + | } | ||
| + | else if (cb instanceof PasswordCallback) | ||
| + | { | ||
| + | ((PasswordCallback) cb).setPassword(password.toCharArray()); | ||
| + | } | ||
| + | else | ||
| + | { | ||
| + | throw new UnsupportedCallbackException(cb); | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | }); | ||
| + | ctx.login(); | ||
| + | // | ||
| + | Subject.doAs(ctx.getSubject(), | ||
| + | { | ||
| + | public Object run() | ||
| + | { | ||
| + | //Do something | ||
| + | return null; | ||
| + | } | ||
| + | }); | ||
| + | ctx.logout(); | ||
| + | </ | ||
| + | |||
| + | ===== Авторизация ===== | ||
| + | |||
| + | ==== Краткое описание проверки пермишена ==== | ||
| + | В Java существует [[http:// | ||
| + | |||
| + | * Проверяется, | ||
| + | * Если равен, то считается что действие разрешено делать. | ||
| + | * Вызывается [[http:// | ||
| + | * Берётся текущий '' | ||
| + | * '' | ||
| + | * Берётся текущая '' | ||
| + | |||
| + | ==== Компоненты системы авторизации ==== | ||
| + | |||
| + | * [[http:// | ||
| + | * [[http:// | ||
| + | * [[http:// | ||
| + | * [[http:// | ||
| + | |||
| + | |||
| + | ==== Внедрение своих правил авторизации ==== | ||
| + | |||
| + | |||
| + | === Principal === | ||
| + | |||
| + | Скорее всего у вас в приложении есть класс '' | ||
| + | |||
| + | == Примерная реализация == | ||
| + | <code java> | ||
| + | public class UserPrincipal implements java.security.Principal { | ||
| + | // ------------------------------ FIELDS ------------------------------ | ||
| + | /** | ||
| + | * Константа для незарегистрированного пользователя. | ||
| + | */ | ||
| + | private static final UserPrincipal nullUserPrincipal = new UserPrincipal (null); | ||
| + | private final User user; | ||
| + | |||
| + | // -------------------------- STATIC METHODS -------------------------- | ||
| + | |||
| + | public static UserPrincipal getPrincipal (final User user) { | ||
| + | return user == null ? nullUserPrincipal : new UserPrincipal (user); | ||
| + | } | ||
| + | |||
| + | // --------------------------- CONSTRUCTORS --------------------------- | ||
| + | |||
| + | protected UserPrincipal (final User user) { | ||
| + | super (); | ||
| + | this.user = user; | ||
| + | } | ||
| + | |||
| + | // ------------------------ CANONICAL METHODS ------------------------ | ||
| + | |||
| + | public boolean equals (final Object obj) { | ||
| + | if (obj == null || !(obj instanceof UserPrincipal)) { | ||
| + | return false; | ||
| + | } | ||
| + | final UserPrincipal o = (UserPrincipal) obj; | ||
| + | final User myUser = this.getUser (); | ||
| + | final User oUser = o.getUser (); | ||
| + | if (myUser == null && oUser == null) { | ||
| + | return true; | ||
| + | } else if (myUser != null && oUser != null) { | ||
| + | return myUser.equals (oUser); | ||
| + | } else { | ||
| + | return false; | ||
| + | } | ||
| + | } | ||
| + | |||
| + | public int hashCode () { | ||
| + | return this.getClass ().hashCode () + (this.user == null ? 13 : this.user.hashCode ()); | ||
| + | } | ||
| + | |||
| + | // ------------------------ INTERFACE METHODS ------------------------ | ||
| + | |||
| + | // --------------------- Interface Nullable --------------------- | ||
| + | |||
| + | public boolean isNull () { | ||
| + | return this.user == null; | ||
| + | } | ||
| + | |||
| + | // --------------------- Interface Principal --------------------- | ||
| + | |||
| + | public String getName () { | ||
| + | return this.getClass ().getName () + " " + (this.user == null ? " | ||
| + | } | ||
| + | |||
| + | // -------------------------- OTHER METHODS -------------------------- | ||
| + | |||
| + | public User getUser () { | ||
| + | return this.user; | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | |||
| + | === Policy === | ||
| + | '' | ||
| + | |||
| + | > **ВНИМАНИЕ** Считается, | ||
| + | |||
| + | |||
| + | |||
| + | === Собираем вместе === | ||
| + | |||
| + | == Установка Policy == | ||
| + | <code java> | ||
| + | Policy.setPolicy (new MyPolicy ()); | ||
| + | </ | ||
| + | |||
| + | == Включение SecurityManager' | ||
| + | <code java> | ||
| + | if (System.getSecurityManager () != null) { | ||
| + | System.setSecurityManager (new SecurityManager ()); | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | == Вызов защищённого кода == | ||
| + | <code java> | ||
| + | try { | ||
| + | final Subject subject = ...; | ||
| + | final T result = Subject.doAs (subject, new PrivilegedExceptionAction< | ||
| + | public Object run () throws IOException, | ||
| + | // | ||
| + | } | ||
| + | }); | ||
| + | } catch (PrivilegedActionException e) { | ||
| + | ... | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | == SecurityUtils == | ||
| + | Пара методов для удобства. | ||
| + | |||
| + | <code java> | ||
| + | public final class SecurityUtils { | ||
| + | public static boolean hasPermission (final Permission permission) { | ||
| + | try { | ||
| + | checkPermission (permission); | ||
| + | return true; | ||
| + | } catch (final SecurityException e) { | ||
| + | return false; | ||
| + | } | ||
| + | } | ||
| + | |||
| + | public static void checkPermission (final Permission permission) throws SecurityException { | ||
| + | if (System.getSecurityManager () != null) { | ||
| + | System.getSecurityManager ().checkPermission (permission); | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | |||
| + | ===== Альтернативы ===== | ||
| + | * [[http:// | ||
| + | FIXME | ||
| + | |||
| + | ===== Permissions Evangelizm ===== | ||
| + | FIXME | ||
| + | |||
| + | ====== JAAS vs Acegi Security ====== | ||
| + | |||
| + | ===== Java Security (JAAS) ===== | ||
| + | {{jsf-ru: | ||
| + | |||
| + | {{jsf-ru: | ||
| + | |||
| + | {{jsf-ru: | ||
| + | |||
| + | {{jsf-ru: | ||
| + | |||
| + | {{jsf-ru: | ||
| + | |||
| + | {{jsf-ru: | ||
| + | |||
| + | {{jsf-ru: | ||
| + | |||
| + | {{jsf-ru: | ||
| + | |||
| + | |||
| + | |||
| + | ===== Acegi Security ===== | ||
| + | |||
| + | {{jsf-ru: | ||
| + | |||
| + | {{jsf-ru: | ||
| + | |||
| + | {{jsf-ru: | ||
| + | |||
| + | {{jsf-ru: | ||
| + | |||
| + | {{jsf-ru: | ||
| + | |||
| + | {{jsf-ru: | ||
| + | |||
| + | {{jsf-ru: | ||
| + | |||
| + | {{jsf-ru: | ||
| + | |||
| + | {{jsf-ru: | ||
| + | |||
| + | {{jsf-ru: | ||
| + | |||
| + | {{jsf-ru: | ||
| + | |||
| + | {{jsf-ru: | ||
| + | |||
| + | При этом следует учитывать, | ||
java_security.txt · Last modified: 2019/06/12 16:08 by 127.0.0.1