此次是将之前的shiro-SpringMVC部署到了idea中,并在此基础上简单实现了一下多Realm的认证
关于idea中web项目的部署,给大家提供两个链接,写的很详细
链接1
链接2
部署过程中遇到的几个问题:
1、配置文件找不到:根据网上的说法,idea中的项目classpath默认为项目的根目录,我还以为可以修改路径解决这个问题。最后才知道,在pom.xml中,必须添加build配置,从而将配置文件拷贝到idea项目的默认资源路径
<build>
<!-- 若不增加此配置,main/config下的配置文件无法被找到-->
<finalName>springmvc-study</finalName>
<resources>
<resource>
<directory>${basedir}/src/main/config</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
<include>*property</include>
</includes>
</resource>
<resource>
<directory>${basedir}/src/main/resources</directory>
</resource>
</resources>
</build>
2、在项目build过程中,始终报commons-fileupload中的一个类找不到:原以为是各依赖之间的版本冲突问题,到处搜索对应的jar包版本,卡了好几个小时,问题依旧。期间还把项目配置中的artifacts也对应补充了一下jar包。最后发现这个方法是对的,但是由于在此项目部署之前,尝试过两个失败的例子,我一直修改的是失败的。。。。此处对自己也是很无语,最后把没用的配置删了,终于好了。
这个问题总结一下就是pom中添加依赖,artifacts中补充put一下。
下面开始多Realm的实践
1、修改shiro配置
<!-- Shiro's main business-tier object for web-enabled applications -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="cacheManager" ref="cacheManager" />
<property name="authenticator" ref="authenticator" />
<property name="realms">
<list>
<ref bean="myShiroRealm" />
<ref bean="myShiroRealm2" />
</list>
</property>
</bean>
<bean id="authenticator" class="com.htp.shiro.UserMultiRealmAuthenticator">
<property name="authenticationStrategy">
<bean class="org.apache.shiro.authc.pam.AtLeastOneSuccessfulStrategy" />
</property>
</bean>
<!-- 項目自定义的Realm -->
<bean id="myShiroRealm" class="com.htp.shiro.UserRealm">
<!-- <property name="cacheManager" ref="cacheManager" /> -->
</bean>
<bean id="myShiroRealm2" class="com.htp.shiro.UserRealm2">
<!-- <property name="cacheManager" ref="cacheManager" /> -->
</bean>
<bean id="allowAllCredentialsMatcher"
class="org.apache.shiro.authc.credential.AllowAllCredentialsMatcher">
</bean>
2、自定义UserMultiRealmAuthenticator.java
package com.htp.shiro;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.pam.AuthenticationStrategy;
/*AllSuccessfulStrategy;
AtLeastOneSuccessfulStrategy
FirstSuccessfulStrategy
*/
import org.apache.shiro.authc.pam.ModularRealmAuthenticator;
import org.apache.shiro.realm.Realm;
import java.util.Collection;
/**
* Created by Administrator on 2018/8/3.
*/
public class UserMultiRealmAuthenticator extends ModularRealmAuthenticator {
//此处其实和源码基本一样
@Override
protected AuthenticationInfo doMultiRealmAuthentication(Collection<Realm> realms, AuthenticationToken token) {
AuthenticationStrategy strategy = getAuthenticationStrategy();
AuthenticationInfo authInfo = strategy.beforeAllAttempts(realms,token);
for (Realm realm:realms){
System.out.println(">>>>>>>>>>>>>>>>><<<<<<<<<<<<");
AuthenticationInfo info = null;
authInfo = strategy.beforeAttempt(realm,token,authInfo);
if (realm.supports(token)){
Throwable t = null;
try {
info = realm.getAuthenticationInfo(token);
}catch (Exception e){
System.out.println(".......");
}
authInfo = strategy.afterAttempt(realm,token,info,authInfo,t);
}
//只需要单个成功的情况
//为何此处还需要做判断,strategy已经封装了
/* if (authInfo != null && !authInfo.getPrincipals().isEmpty()){
return authInfo;
}
else{
}*/
}
authInfo = strategy.afterAllAttempts(token,authInfo);
return authInfo;
// return super.doMultiRealmAuthentication(realms, token);
}
}
其实UserMultiRealmAuthenticator 也没必要自定义,实现和父类基本一致,重写的doMultiRealmAuthentication()基本都是父类里自带的。不同的可能就是遇到异常的自定义处理。
运行过程中,通过断点跟踪调试,明白了shiro中Realm的执行前后过程。多个realm之间的执行顺序与配置的顺序有关。