4

Apache Shiro を使用する Tapestry-Security を使用しています

承認と認証を処理するカスタム レルムがあります。私たちの認証は、技術的には、ユーザー名とロールのセットを返すリモート サービスを使用して行われます。ユーザー名をカスタム AuthenticationToken に渡すだけで、ローカル データベースにクエリを実行し、SimpleAuthenticationInfo を設定できます。

リモート サービスから返されたロールのリストを使用して、AuthorizationInfo doGetAuthorizationInfo メソッドを設定する方法がわかりません。以下は、レルムを設定するために使用しているコードです。

ログインクラス

//Remote authentication service
RemoteLoginClient client = new RemoteLoginClient();
RemoteSubject authenticate = client.authenticate(username, password);

//tapestry security authentication
Subject currentUser = SecurityUtils.getSubject();
CustomAuthenticationToken token = new 
    CustomAuthenticationToken(authenticate.getUsername());
System.out.println("roles" + authenticate.getRoles());

currentUser.login(token);

customRealm 内の AuthorizationInfo メソッド public class CustomRealm extends AuthorizingRealm {

protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
    CustomAuthenticationToken upToken = (CustomAuthenticationToken ) token;
    String email = upToken.getUsername();

    ApplicationUser applicationUser = (ApplicationUser) session.createCriteria(ApplicationUser.class)
            .add(Restrictions.like("email", email + "%"))
            .uniqueResult();

    if (applicationUser == null) {
        throw new UnknownAccountException("User doesn't exist in EPRS database");
    }

    return buildAuthenticationInfo(applicationUser.getId());
}

protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
//Not sure how to populate the principle or
//read the principle to populate the SimpleAuthorizationInfo
    return new SimpleAuthorizationInfo(roleNames);
}
4

2 に答える 2

7

AuthorizingRealm認証と承認の両方が必要な場合は、拡張を開始することをお勧めします。また、PepperBob が既に述べているように、Accountインターフェイスとその実装は、単一のインターフェイスで認証と承認の両方をサポートしているため、 andとSimpleAccountの別々のコードはあまり必要なく、両方から同じオブジェクトを返すことができます。メソッド。doGetAuthenticationInfo()doGetAuthorizationInfo()

認証情報を取得するには、次の 2 つのことを行う必要があります。

  • パラメータとして渡されたプリンシパル コレクション (ほとんどの場合、とにかく 1 つのプリンシパルのみを含む) から、getAvailablePrincipal()メソッド (できちんと定義済み) を介して使用可能なプリンシパルを取得しますAuthorizingRealm
  • setRoles()ロールをロードして、アカウント オブジェクトに渡します。

...これで完了です。

追加するために編集:

これは、必要になるまでロールを保存するための非常に簡単な方法です。実際の認証は、 に依存するレルムで行われることに注意してくださいRemoteLoginClient

public class MyRealm extends AuthorizingRealm {

    private RemoteLoginClient client = ...;

    private final Map<String, Set<String>> emailToRoles = new ConcurrentHashMap<>();

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(
             AuthenticationToken token) {
        final UsernamePasswordToken userPass = (UsernamePasswordToken) token;

        final RemoteSubject authenticate = this.client.authenticate(
            userPass.getUserName(), userPass.getPassword());
        if (authenticate != null) { //assuming this means success
            this.emailToRoles.put(userPass.getUserName(), authenticate.getRoles());
            return new SimpleAuthenticationInfo(...);
        } else {
            return null;
        }
    }

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(
            PrincipalCollection principals) {
         final String username = (String) principals.getPrimaryPrincipal();
         final Set<String> roles = this.emailToRoles.get(username);
         return new SimpleAuthorizationInfo(roles);
    }

}
于 2012-05-02T11:27:39.870 に答える
3

私は自分の質問に答え、他の誰かが助けを必要とする場合や私の解決策を改善するためにこれを投稿したいと思いました.

Login.class メソッド

Object onSubmit() {
    try {
        //Remote Authentication
        RemoteLoginClient client = new RemoteLoginClient ();
        RemoteSubject authenticate = client.authenticate(formatUsername(username), password);

        //tapestry security authentication
        Subject currentUser = SecurityUtils.getSubject();
        CustomAuthenticationToken token = new CustomAuthenticationToken(authenticate.getUsername(), authenticate.getRoles());

        currentUser.login(token);
    } //catch errors
}

//リモート認証サービスから設定されたユーザー名とロールを保持するために使用されるカスタム トークン。

public class CustomAuthenticationToken implements AuthenticationToken {

private String username;
private Set<String> roles;

public CustomAuthenticationToken(String username, Set<String> roles) {
    this.username = username;
    this.roles = roles;
}

getters/setters

//ローカルの認証と承認を処理するために使用されるカスタム レルム。

public class CustomRealm extends AuthorizingRealm {

//Hibernate Session
private final Session session;
public static final String EMPTY_PASSWORD = "";

public CustomRealm(Session session) {
    this.session = session;
    setCredentialsMatcher(new AllowAllCredentialsMatcher());
    setAuthenticationTokenClass(CustomAuthenticationToken.class);
}

protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
    CustomAuthenticationToken customToken = (CustomAuthenticationToken) token;
    String email = customToken.getUsername();

    User user = (User) session.createCriteria(User.class)
            .add(Restrictions.like("email", email+ "%"))
            .uniqueResult();

    if (user == null) {
        throw new UnknownAccountException("User doesn't exist in local database");
    }

    return new SimpleAuthenticationInfo(new CustomPrincipal(user, customToken.getRoles()), EMPTY_PASSWORD, getName());
}

protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
    return new SimpleAuthorizationInfo(((CustomPrincipal) principals.getPrimaryPrincipal()).getRoles());
}

}

//ユーザー オブジェクトとロールを保持するために使用されるカスタム プリンシパル public class CustomPrincipal {

private User user;
private Set<String> roles;

public CustomPrincipal() {
}

public CustomPrincipal(User user, Set<String> roles) {
    this.user = user;
    this.roles = roles;
}

getters/setters
于 2012-05-03T13:09:25.033 に答える