Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在Shiro中从多个领域获取特定领域进行授权?_Java_Spring_Shiro - Fatal编程技术网

Java 如何在Shiro中从多个领域获取特定领域进行授权?

Java 如何在Shiro中从多个领域获取特定领域进行授权?,java,spring,shiro,Java,Spring,Shiro,我是Spring和Shiro平台的新手 我有两个url集/admin/--和/vendor/--。两个客户端集都在使用特定领域进行身份验证。我扩展了modulerarelauthenticator类来选择正确的域进行身份验证 ModularRealAuthenticator.java @Override protected AuthenticationInfo doAuthenticate(AuthenticationToken authenticationToken) throws Authe

我是Spring和Shiro平台的新手

我有两个url集
/admin/--
/vendor/--
。两个客户端集都在使用特定领域进行身份验证。我扩展了
modulerarelauthenticator
类来选择正确的域进行身份验证

ModularRealAuthenticator.java

@Override
protected AuthenticationInfo doAuthenticate(AuthenticationToken authenticationToken) throws AuthenticationException {
    assertRealmsConfigured();
    MultiLoginAuthenticationToken mlat = null;
    Realm loginRealm = null;

    if (!(authenticationToken instanceof MultiLoginAuthenticationToken)) {
        throw new AuthenticationException("Unrecognized token , not a typeof MultiLoginAuthenticationToken ");
    } else {
        mlat = (MultiLoginAuthenticationToken) authenticationToken;
        logger.debug("realm name is : {}", mlat.getRealmName());
        loginRealm = lookupRealm(mlat.getRealmName());
    }

    return doSingleRealmAuthentication(loginRealm, mlat);

}

protected Realm lookupRealm(String realmName) throws AuthenticationException {
    Collection<Realm> realms = getRealms();
    for (Realm realm : realms) {
        if (realm.getName().equalsIgnoreCase(realmName)) {
            logger.debug("look up realm name is : {}", realm.getName());
            return realm;
        }
    }
    throw new AuthenticationException("No realm configured for Client " + realmName);
}
@覆盖
受保护的AuthenticationInfo DoAuthentication(AuthenticationToken AuthenticationToken)引发AuthenticationException{
assertRealmsConfigured();
MultiLoginAuthenticationToken mlat=null;
Realm loginrelm=null;
if(!(MultiLoginAuthenticationToken的authenticationToken实例){
抛出新的AuthenticationException(“无法识别的令牌,不是MultiLoginAuthenticationToken的类型”);
}否则{
mlat=(MultiLoginAuthenticationToken)authenticationToken;
debug(“域名为:{}”,mlat.getRealmName());
loginrelm=lookupRealm(mlat.getreallname());
}
返回真实身份验证(loginRealm,mlat);
}
受保护领域lookupRealm(字符串realmName)引发AuthenticationException{
集合领域=getRealms();
for(领域:领域){
if(realm.getName().equalsIgnoreCase(realmName)){
debug(“查找领域名称为:{}”,realm.getName());
回归境界;
}
}
抛出新的AuthenticationException(“没有为客户端配置域”+realmName);
}
但是,当我从不同的数据源集向两个客户端(管理员和供应商)分配角色和权限时。它按照我在applicationContext.xml文件中定义的顺序迭代领域

My ApplicationContext.xml

<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">

    <property name="authenticator">
        <bean class="com.yatra.mp.security.MultiLoginAuthenticator"/>
    </property>

    <!-- Single realm app (realm configured next, below). If you have multiple 
        realms, use the 'realms' property instead. -->
    <property name="realms">
        <util:list>
            <ref bean="adminAuthRealm" />
            <ref bean="vendorAuthRealm" />              
        </util:list>
    </property>

    <property name="cacheManager" ref="cacheManager" />
</bean>

在这两个领域中,都扩展了授权领域类,并且都有DogeAuthorizationInfoDogeAuthenticationInfo方法。我在其中定义了自定义实现


是否需要扩展模块化Authorizer类?如果是,您能告诉我我使用了哪种方法覆盖吗?

您可以将域信息添加到PrincipalCollection中,您可以将其包装在AuthenticationInfo中。它是主体集合中添加的令牌,在后续shiro调用中结转。如果该信息与您的领域不匹配,您可以在身份验证中使用该信息进行跳过。这实际上是我们在自定义领域所做的:

public class OurRealmImpl extends AuthorizingRealm

...
    @Override
    public AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) {
        ... //check if user exists and read passwordhash
        Login ourLoginToken = ...
        SimplePrincipalCollection principalCollection = new SimplePrincipalCollection(ourLoginToken, realmName);
        return new SimpleAuthenticationInfo(principalCollection, passwordHash);
    }

    @Override
    public AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        Collection collection = principals.fromRealm(realmName);
        if (collection.isEmpty()) {
           return null;
        }
        Login login = (Login) collection.iterator().next();
        ... get the rights and return authorization
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.addStringPermissions(permissionStrings);
        return info;
    }

我也遇到了这个问题。最后,我解决了它。步骤如下:

1)让一个新类来扩展ModuleRarelAuthorizer。

public class OurModularRealmAuthorizer extend ModularRealmAuthorizer{
  private map<string,OurAuthorizerRealm> mRealms;
  private map<string,OurAuthorizerRealm> getMRealms(){return mRealms;}
  private void setMRealms(map<string,OurAuthorizerRealm> mrealms){
      this.mRealms = mrealms;
      Collection<Realm> tmpRealms = new ArrayList<Realm>();

        for (OurAuthorizerRealm value : mrealms.values()) {
            Realm realm = (Realm) value;
            tmpRealms.add(realm);
        }

        this.realms = tmpRealms;/*setting realms*/
  }
}
public类ourModuleArrelAuthorizer扩展ModuleArrelAuthorizer{
私人地图;
私有映射getMRealms(){return mRealms;}
专用void setMRealms(映射mrealms){
this.mRealms=mRealms;
集合tmpRealms=newarraylist();
对于(OurAuthorizerRealm值:mrealms.values()){
领域=(领域)值;
tmpRealms.add(领域);
}
this.realms=tmpRealms;/*设置realms*/
}
}
2。spring shiro.xml:

<bean id="ourModularRealmAuthorizer" class="xx.xxx.shiro.realm.ShiroModularRealmAuthorizer">
        <property name="mRealms">
            <map>
                <entry key="ourAuthorizerRealm1" value-ref="ourAuthorizerRealm1" />
                <entry key="ourAuthorizerRealm2" value-ref="ourAuthorizerRealm2" />
            </map>
        </property>
    </bean>
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <property name="authenticator" ref="ourModularRealmAuthenticator"></property>
        <property name="authorizer" ref="ouModularRealmAuthorizer"></property>
        <property name="cacheManager" ref="shiroCacheManager"></property>
    </bean>


好的。

不清楚您的实际问题是什么。您好,我的问题是:我的应用程序中有两种类型的用户(管理员和供应商)。这两种类型的用户都使用两个表进行身份验证,并且都具有不同的权限,即使用同一数据库中的不同表进行授权。我使用两个领域进行身份验证和授权,这两种类型的用户正在扩展AuthorizationRealm类。我在上面写了自定义验证器,它调用正确的域进行身份验证。但在进行授权时,它调用了错误的领域(即,领域正在按照我们在applicationContext.xml文件中定义的顺序执行授权)。所以我的问题是如何为特定用户获得正确的授权域?因为这两个领域都有doGetAuthenticationInfo方法来为特定类型的用户分配角色和权限。如果你还有其他问题,请告诉我。我被困在这个问题上好几天了。请帮我做这件事。提前谢谢。你好,沃特,非常感谢。我已经覆盖了这两个领域中的“supports”方法。这就是为什么我能够调用正确的域进行身份验证。但是我不明白为什么它没有被要求授权。。您能告诉我原因吗?我在这两个领域都添加了以下代码:
code@Override public boolean supports(AuthenticationToken){if(MultiLoginAuthenticationToken的令牌实例){return((MultiLoginAuthenticationToken)token.getRealmName().equalsIgnoreCase(“AdminAuthRealm”);}return false;}
你好,我已经读过Shiro的文章了。据我理解的概念,支持只为身份验证而不是授权调用的方法。就我而言,身份验证工作正常。我在授权过程中面临问题。请让我知道如何处理此问题?谢谢。完全误解了这个问题。我已将答案改为“我希望你是在问”。抱歉耽搁了。