Tomcat從零開始(十六)-----tomcat安全

來源:互聯網
上載者:User

 

Servlet

    SecurityCollection securityCollection = new SecurityCollection();    securityCollection.addPattern("/");    securityCollection.addMethod("GET");    SecurityConstraint constraint = new SecurityConstraint();    constraint.addCollection(securityCollection);    constraint.addAuthRole("manager");    LoginConfig loginConfig = new LoginConfig();    loginConfig.setRealmName("Realm");        Realm realm = new SimpleRealm();    context.setRealm(realm);    context.addConstraint(constraint);    context.setLoginConfig(loginConfig);
我們看第一行,建立了一個securityCollection隨心,之後addPattern()就是設定需要安全限制的url,之後的addMethod不多解釋了- -GET,POST沒啥說的。之後的一段就是把secuityCollection交給constraint,之後設定只有Manager這個角色才能訪問。最後與container進行關聯。

  private void createUserDatabase() {    User user1 = new User("Victory", "test");    user1.addRole("manager");    user1.addRole("programmer");    User user2 = new User("Mrc", "Chri");    user2.addRole("programmer");    users.add(user1);    users.add(user2);  }  class User {    public User(String username, String password) {      this.username = username;      this.password = password;    }    public String username;    public ArrayList roles = new ArrayList();    public String password;    public void addRole(String role) {      roles.add(role);    }    public ArrayList getRoles() {      return roles;    }  }

   我們會發現,在我們的realm的預設構造器中調用了createUserDatabase()之後,這個方法建立了一個使用者,使用了user這個內部類。這個realm全部的代碼我就不貼了- -這個去源碼看就妥了。

         同時,我們知道這個authenticator也是一個valve,所以我們自然而然的想到了pipeline,之後很自然的想到,它應該寫在ContextConfig中。添加的代碼如下

  private synchronized void authenticatorConfig() {    // Does this Context require an Authenticator?    SecurityConstraint constraints[] = context.findConstraints();    if ((constraints == null) || (constraints.length == 0))      return;    LoginConfig loginConfig = context.getLoginConfig();    if (loginConfig == null) {      loginConfig = new LoginConfig("NONE", null, null, null);      context.setLoginConfig(loginConfig);    }    // Has an authenticator been configured already?    Pipeline pipeline = ((StandardContext) context).getPipeline();    if (pipeline != null) {      Valve basic = pipeline.getBasic();      if ((basic != null) && (basic instanceof Authenticator))        return;      Valve valves[] = pipeline.getValves();      for (int i = 0; i < valves.length; i++) {        if (valves[i] instanceof Authenticator)        return;      }    }    else { // no Pipeline, cannot install authenticator valve      return;    }    // Has a Realm been configured for us to authenticate against?    if (context.getRealm() == null) {      return;    }    // Identify the class name of the Valve we should configure    String authenticatorName = "org.apache.catalina.authenticator.BasicAuthenticator";    // Instantiate and install an Authenticator of the requested class    Valve authenticator = null;    try {      Class authenticatorClass = Class.forName(authenticatorName);      authenticator = (Valve) authenticatorClass.newInstance();      ((StandardContext) context).addValve(authenticator);      System.out.println("Added authenticator valve to Context");    }    catch (Throwable t) {    }  }

當然別忘了在lifecycleEvent這個方法中調用它。



另外的一種擷取登入賬戶資料的方法是通過xml讀取。代碼如下,只要把bootstrap更改一下就行了,之後添加一個SimpleUserDatabaseRealm類就可以了。先看SimpleUserDatabaseRealm的代碼

public class SimpleUserDatabaseRealm extends RealmBase {  protected UserDatabase database = null;  protected static final String name = "SimpleUserDatabaseRealm";  protected String resourceName = "UserDatabase";  public Principal authenticate(String username, String credentials) {    // 檢測這個使用者名稱的使用者是否存在    User user = database.findUser(username);    if (user == null) {      return (null);    }    boolean validated = false;    if (hasMessageDigest()) {      validated = (digest(credentials).equalsIgnoreCase(user.getPassword()));    }    else {      validated = (digest(credentials).equals(user.getPassword()));    }    if (!validated) {      return null;    }    ArrayList combined = new ArrayList();    Iterator roles = user.getRoles();    while (roles.hasNext()) {      Role role = (Role) roles.next();      String rolename = role.getRolename();      if (!combined.contains(rolename)) {        combined.add(rolename);      }    }    Iterator groups = user.getGroups();    while (groups.hasNext()) {      Group group = (Group) groups.next();      roles = group.getRoles();      while (roles.hasNext()) {        Role role = (Role) roles.next();        String rolename = role.getRolename();        if (!combined.contains(rolename)) {          combined.add(rolename);        }      }    }    return (new GenericPrincipal(this, user.getUsername(),      user.getPassword(), combined));  }  protected Principal getPrincipal(String username) {    return (null);  }  protected String getPassword(String username) {    return null;  }  protected String getName() {    return this.name;  }  public void createDatabase(String path) {    database = new MemoryUserDatabase(name);    ((MemoryUserDatabase) database).setPathname(path);    try {      database.open();    }    catch (Exception e)  {    }  }}

Bootstrap。

    SecurityConstraint constraint = new SecurityConstraint();    constraint.addCollection(securityCollection);    constraint.addAuthRole("manager");    LoginConfig loginConfig = new LoginConfig();    loginConfig.setRealmName("Simple User Database Realm");    // add realm    Realm realm = new SimpleUserDatabaseRealm();    ((SimpleUserDatabaseRealm) realm).createDatabase("conf/tomcat-users.xml");    context.setRealm(realm);    context.addConstraint(constraint);    context.setLoginConfig(loginConfig);

這個相信不用我多說,看看代碼發現時訪問conf/tomcat-users.xml這個檔案擷取帳號,從而來驗證的。

xml的檔案內容如下

<?xml version='1.0' encoding='utf-8'?><tomcat-users>  <role rolename="tomcat"/>  <role rolename="programmer"/>  <role rolename="manager"/>  <role rolename="admin"/>  <user username="tomcat" password="tomcat" roles="tomcat"/>  <user username="victory" password="tomcat" roles="programmer"/>  <user username="both" password="tomcat" roles="tomcat,programmer"/>  <user username="admin" password="password" roles="admin,manager"/></tomcat-users>


相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.