Java 如何在Shiro中从多个领域获取特定领域进行授权?
我是Spring和Shiro平台的新手 我有两个url集Java 如何在Shiro中从多个领域获取特定领域进行授权?,java,spring,shiro,Java,Spring,Shiro,我是Spring和Shiro平台的新手 我有两个url集/admin/--和/vendor/--。两个客户端集都在使用特定领域进行身份验证。我扩展了modulerarelauthenticator类来选择正确的域进行身份验证 ModularRealAuthenticator.java @Override protected AuthenticationInfo doAuthenticate(AuthenticationToken authenticationToken) throws Authe
/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>
在这两个领域中,都扩展了授权领域类,并且都有DogeAuthorizationInfo和DogeAuthenticationInfo方法。我在其中定义了自定义实现
是否需要扩展模块化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的文章了。据我理解的概念,支持只为身份验证而不是授权调用的方法。就我而言,身份验证工作正常。我在授权过程中面临问题。请让我知道如何处理此问题?谢谢。完全误解了这个问题。我已将答案改为“我希望你是在问”。抱歉耽搁了。