LoginSignup
0
0

More than 5 years have passed since last update.

Apache Shiro Quickstart その3

Last updated at Posted at 2017-08-17

前回は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を試してみます。テーブル定義も不要だし、JSONをPOSTするだけでユーザー情報を管理できます。

$ 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

MongoUserPasswordRealm.java
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/

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0