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/