User Tools

Site Tools


java_security

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
Last revisionBoth sides next revision
java_security [2007/02/09 11:46] – создано slonopotamusjava_security [2007/04/10 10:39] slonopotamus
Line 1: Line 1:
-[[start|На главную]] 
  
-====== Реализация системы безопасности в Java ====== 
-  Всё нижеописанное исходит из предположения что в Sun хорошо подумали когда 
-  проектировали пермишены, секьюрити-менеджер и всё с ними связанное. 
- 
- 
-===== О чём это вообще ===== 
-В типичном веб-приложении далеко не каждый пользователь может менять любые данные. У кого-то есть доступ только на чтение, кто-то может менять только свои данные, кто-то только данные пользователей из определённой группы или находящиеся в определённом состоянии. Возникает задача разграничивания прав. Есть несколько вариантов её решения. Вариант первый - логика разрешения/запрещения жёстко задаётся в коде. Существует жёстко заданный набор групп с наборами правам. Этот подход работает только до тех пор пока не возникает необходимости изменить эти наборы. Другой подход связан с динамическим созданием групп и динамическим же назначением им прав. И логика по проверке просто проверяет, есть ли у текущего пользователя право на то действие, которое он пытается совершить. 
-==== Что защищать ==== 
-Любые данные. 
-==== Зачем защищать ==== 
-Чтобы разделять, кому что можно, а кому что нельзя делать. 
- 
-===== Краткое описание проверки пермишена ===== 
-В Java существует [[http://java.sun.com/j2se/1.5.0/docs/guide/security/spec/security-specTOC.fm.html|встроенный механизм прав]]. 
- 
-  * Проверяется, не равен ли ''null'''у ''System#getSecurityManager()''. 
-    * Если равен, то считается что действие разрешено делать. 
-  * Вызывается [[http://java.sun.com/j2se/1.5.0/docs/api/java/lang/SecurityManager.html#checkPermission(java.security.Permission)|SecurityManager#checkPermission(java.security.Permission)]] 
-  * Берётся текущий ''AccessControlContext'' и вызывается у него метод [[http://java.sun.com/j2se/1.5.0/docs/api/java/security/AccessControlContext.html#checkPermission(java.security.Permission)|AccessControlContext#checkPermission(java.security.Permission)]] 
-  * ''AccessControlContext'' итерейтится по содержащимся в нём ''ProtectionDomain'''ам и у них вызывается метод [[http://java.sun.com/j2se/1.5.0/docs/api/java/security/ProtectionDomain.html#implies(java.security.Permission)|ProtectionDomain#implies(java.security.Permission)]] 
-  * Берётся текущая ''Policy'', у которой вызывается метод [[http://java.sun.com/j2se/1.5.0/docs/api/java/security/Policy.html#implies(java.security.ProtectionDomain, java.security.Permission)|Policy#implies(java.security.ProtectionDomain, java.security.Permission)]] с данным ''ProtectionDomain''ом. 
- 
-===== Компоненты системы авторизации ===== 
- 
-  * [[http://java.sun.com/j2se/1.5.0/docs/api/java/lang/SecurityManager.html|SecurityManager]] - просто фасад над всей системой прав. 
-  * [[http://java.sun.com/j2se/1.5.0/docs/api/java/security/AccessControlContext.html|AccessControlContext]] - контекст с информацией о том, в каких ''ProtectionDomain'''ах выполняется сейчас код. 
-  * [[http://java.sun.com/j2se/1.5.0/docs/api/java/security/ProtectionDomain.html|ProtectionDomain]] - содержит информацию об URL'ах (возможно с сертификатами), из которых получен выполняющийся код, ''ClassLoader'', через который этот код был получен и (**внимание**) коллекцию [[http://java.sun.com/j2se/1.5.0/docs/api/java/security/Principal.html|Principal]]'ов, от имени которых код выполняется. 
-  * [[http://java.sun.com/j2se/1.5.0/docs/api/java/security/Policy.html|Policy]] - хранилище пермишенов, которое определяет какие права у кого есть. 
- 
- 
-===== Внедрение своих правил авторизации ===== 
- 
- 
-==== Principal ==== 
- 
-Скорее всего у вас в приложении есть класс ''User''. Нужно будет написать реализацию ''Principal'''а для него (Внимание! Не надо делать так чтобы ваш ''User'' реализовывал ''Principal'''а, т.к. отсутствие юзера не означает отсутствие ''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 ? "unregistered" : this.getUser ().getUserId ()); 
-  } 
- 
-  // -------------------------- OTHER METHODS -------------------------- 
- 
-  public User getUser () { 
-    return this.user; 
-  } 
-} 
-</code> 
- 
- 
-==== Policy ==== 
-''Policy'' - это как раз то, куда надо всовывать свой код, чтобы делать проверку прав по своей базе, а не по стандартной реализации в policy-файле. Делается это просто - пишется свой класс, наследующийся от ''Policy'' (внимание, если в вашем приложении права могут динамически изменяться, то надо переопределять метод ''implies'', т.к. в стандартной реализации он активно занимается кэшированием пермишенов. 
- 
-> **ВНИМАНИЕ** Считается, что право разрешено, если оно разрешено для **ВСЕХ** ProtectionDomain'ов, находящихся в ''AccessControlContext'''е вызывающего кода. 
- 
- 
- 
-==== Собираем вместе ==== 
- 
-=== Установка Policy === 
-<code java> 
-Policy.setPolicy (new MyPolicy ()); 
-</code> 
- 
-=== Включение SecurityManager'а === 
-<code java> 
-if (System.getSecurityManager () != null) { 
-  System.setSecurityManager (new SecurityManager ()); 
-} 
-</code> 
- 
-=== Вызов защищённого кода === 
-<code java> 
-try { 
-  final Subject subject = ...; 
-  final T result = Subject.doAs (subject, new PrivilegedExceptionAction<T>() { 
-    public Object run () throws IOException, ServletException { 
-      //выполнить какой-то код, защищённый правами. 
-    } 
-  }); 
-} catch (PrivilegedActionException e) { 
-  ... 
-} 
-</code> 
- 
-=== 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); 
-    } 
-  } 
-} 
-</code> 
- 
- 
-===== Альтернативы ===== 
-  * [[http://acegisecurity.org/|Acegi Security]] 
-FIXME 
- 
-===== Permissions Evangelizm ===== 
-FIXME 
java_security.txt · Last modified: 2019/06/12 16:08 by 127.0.0.1