Shiro 快速入门指南 第三部分

上次我使用了Apache Derby。但是因为下面这样的方式已经过时了,所以我想用MongoDB来管理用户信息。
http://qiita.com/namikitakeo/items/e711d7374f645f667ac6

ij> CREATE TABLE USERS (ID varchar(255) PRIMARY KEY NOT NULL, PASS varchar(255) NOT NULL);
ij> CREATE TABLE ROLES (ID varchar(255) PRIMARY KEY NOT NULL, ROLE varchar(255) NOT NULL);
ij> INSERT INTO USERS (ID,PASS) VALUES ('root','password');
ij> INSERT INTO ROLES (ID,ROLE) VALUES ('root','admin');

启动MongoDB服务。

$ sudo su -
# /usr/bin/mongod --logpath /var/log/mongodb/mongod.log --rest

我会尝试使用REST API。不需要表定义,只需通过POST JSON即可管理用户信息。

$ curl http://localhost:28017/shiro/users/
$ curl -d '{id:"root", pass:"secret", roles:["user","admin"]}' http://localhost:28017/shiro/users/
$ curl -d '{id:"guest", pass:"guest", roles:["guest"]}' http://localhost:28017/shiro/users/
$ curl http://localhost:28017/shiro/users/

您可以通过命令行进行管理,而不仅限于SQL,在用户信息数据库进行搜索。

$ mongo
> show dbs;
> use shiro;
> show collections;
> db.users.find();
> exit;

我会参考这里的内容,从数据库中获取用户信息。我对原始文件进行了较大的修改。
https://github.com/TensorWrench/shiro-mongodb-realm

package com.tensorwrench.shiro.realm;

import java.util.List;

import org.apache.shiro.authc.*;
import org.apache.shiro.authz.*;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import com.mongodb.*;

/**
 *  Does authentication and authorization from a MongoDB.
 *  Expects the documents to have a several fields:
 *  <ul>
 *  <li> passwordAuthentication - object with authentication info
 *  <ul>
 *     <li>name - user name
 *     <li>password - password hash
 *  </ul>
 *  <li>roles - an array of roles
 *  <ul>
 */
public class MongoUserPasswordRealm extends AuthorizingRealm {
    protected DBCollection collection;

    public MongoUserPasswordRealm() {
        MongoClient mongo = new MongoClient("localhost",27017);
        DB db = mongo.getDB("shiro");
        collection = db.getCollection("users");
    }

    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof UsernamePasswordToken;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authToken) throws AuthenticationException {
        if(!(authToken instanceof UsernamePasswordToken)) {
            throw new AuthenticationException("This realm only supports UsernamePasswordTokens");
        }
        UsernamePasswordToken token=(UsernamePasswordToken) authToken;

        if(token.getUsername() == null) {
            throw new AuthenticationException("Cannot log in null user");
        }

        return findPasswordForUsername(token.getUsername());
    }

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();
        DBObject obj= collection.findOne(new BasicDBObject("id",principals.getPrimaryPrincipal().toString()));
        if(obj != null) {
            for(Object r: (List<Object>) obj.get("roles")) {
                info.addRole(r.toString());
            }
        }

        return info;
    }

    /**
     * Does the actual mechanics of creating the Authentication info object from the database.
     */
    public AuthenticationInfo findPasswordForUsername(String username) {
        DBObject obj= collection.findOne(new BasicDBObject("id",username));

        if(obj == null) {
            throw new UnknownAccountException("Unkown user " + username);
        }

        String password=(String)obj.get("pass");
        return new SimpleAuthenticationInfo(username, password, getName());
    }
}

转到web目录。

$ cd shiro-root-1.3.2/samples/web

修改shiro.ini如下。

defaultRealm = com.tensorwrench.shiro.realm.MongoUserPasswordRealm

#jdbcRealm=org.apache.shiro.realm.jdbc.JdbcRealm
#jdbcRealm.authenticationQuery = select pass from users where id = ?
#jdbcRealm.userRolesQuery = select role from roles where id = ?

#ds=com.jolbox.bonecp.BoneCPDataSource
#ds.driverClass=org.apache.derby.jdbc.ClientDriver
#ds.jdbcUrl=jdbc:derby://localhost:1527/test
#jdbcRealm.dataSource=$ds

请按照以下方式将依赖项添加到pom.xml文件中。

<dependency>
    <groupId>org.mongodb</groupId>
    <artifactId>mongodb-driver</artifactId>
    <version>3.5.0</version>
</dependency>

运行 Jetty。

$ mvn jetty:run

请使用Web浏览器访问以下URL:
http://localhost:9080/