springmvc 整合 shiro 先两种方式 一种用xml文件 另一种用 java类注解注入
先上 xml版本:
本文只有登录和登录拦截
- web.xml 文件中先写:
<!--配置shiro过滤器-->
<filter>
<filter-name>shiroFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<async-supported>true</async-supported>
<init-param>
<param-name>targetFilterLifecycle</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>shiroFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--配置shiro过滤器 - End-->
注意:
两个shiroFilter
名称与下面的xml文件里的第一个id相同
第二步: spring容器扫描 spring-shiro.xml (通常是web里面扫描spring上下文)
这里是web.xml
<!-- 配置spring上下文参数 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-*.xml</param-value>
</context-param>
<!-- 配置spring上下文参数- End -->
这里是编写的 spring-shiro.xml 文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<!-- Shiro的Web过滤器 -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<!-- Shiro的安全管理器,所有关于安全的操作都会经过SecurityManager -->
<property name="securityManager" ref="securityManager"/>
<!-- 系统认证提交地址,如果用户退出即session丢失就会访问这个页面(也可以写成访问控制)-->
<property name="loginUrl" value="/login.html"/>
<!-- 权限验证失败跳转的页面,需要配合Spring的ExceptionHandler异常处理机制使用 -->
<property name="unauthorizedUrl" value="/unauthorized.jsp"/>
<property name="filters">
<util:map>
<entry key="authc" value-ref="formAuthenticationFilter"/>
</util:map>
</property>
<!-- 自定义的过滤器链,从上向下执行,一般将`/**`放到最下面 -->
<property name="filterChainDefinitions">
<value>
<!--这里是登录之前 拦截的东西,
比如静态资源如果拦截了页面的css样式都没有了只有最基本的input框等
比如拦截了登录方法,或者登录页面,那就无法登录了,所以登录页面和方法要开放-->
/login.html = anon <!--登录页面-->
/login.jsp = anon <!--登录页面-->
/login = anon <!--登录方法-->
/loginUser =anon <!--登录方法-->
<!-- //*.html = authc --> <!--拦截所有以html结尾的文件
这里要放在最后面 因为是从上往下按顺序走-->
<!--authc 结尾的意思是没有登录就不能访问-->
<!-- /** = authc-->
<!-- <!– 静态资源不拦截 –>
/static/** = anon
/lib/** = anon
/js/** = anon
<!– 登录页面不拦截 –>
/login.html = anon
/login.jsp = anon
/login = anon
<!– Shiro提供了退出登录的配置`logout`,会生成路径为`/logout`的请求地址,访问这个地址即会退出当前账户并清空缓存 –>
/logout = logout
<!– user表示身份通过或通过记住我通过的用户都能访问系统 –>
/index.jsp = user
<!– `/**`表示所有请求,表示访问该地址的用户是身份验证通过或RememberMe登录的都可以 –>
/** = user-->
</value>
</property>
</bean>
<!-- 基于Form表单的身份验证过滤器 -->
<bean id="formAuthenticationFilter" class="org.apache.shiro.web.filter.authc.FormAuthenticationFilter">
<property name="usernameParam" value="username"/>
<property name="passwordParam" value="password"/>
<property name="loginUrl" value="/login.html"/>
</bean>
<!-- 安全管理器 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="MyShiroRealm"/>
</bean>
<!-- Realm实现 -->
<bean id="MyShiroRealm" class="com.kdmins.shiro.MyShiroRealm">
<!-- 配置MD5加密,若不进行MD5加密,这段代码不用 -->
<!-- <property name="credentialsMatcher">
<bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
<!– MD5加密 –>
<property name="hashAlgorithmName" value="md5"/>
<!– 加密次数 –>
<property name="hashIterations" value="1"/>
</bean>
</property>
<!–关闭认证缓存–>
<property name="AuthenticationCachingEnabled" value="false"></property>-->
</bean>
</beans>
第三步: 写MyRealm 类 因为上面最后一个 注入的是咱们自定义的Realm类
public class MyShiroRealm extends AuthorizingRealm {
/**
* shiro 用户权限管理
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {
// TODO Auto-generated method stub
return null;
}
/**
* shiro登录认证管理
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
//获取token令牌里的用户信息
Object principal = authenticationToken.getPrincipal();
//强转成String 类型
String username = (String) principal;
//添加到Map 属性
Map<String, String> map = new HashMap<String, String>();
map.put("username", username);
//根据用户姓名得到用户信息
//Map userinfo = userInfoDao.getUserInfoByName(map);
//判断如果有这个用户信息 开始验证
if (userinfo!=null) {
//得到用户密码
//String password = (String) userinfo.get("USER_PASSWORD");
// 如果是单纯的测试可以在此处把账号密码写死
String password = "mima" //密码
//获取realm 的名称
String realName = this.getName();
//交给shiro框架进行比对 (shiro框架自行比对账号密码)
SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(username,password,realName);
return authenticationInfo;
}
return null;
}
单纯的登录验证框架就已经搭好了,接下来编写登录:
此处只写后端: 上一个简单的逻辑
//登录 这里要注意一下 Mapping登录地址 shiro 一定不要拦截,否则登录都拦截了 怎么登录?
@RequestMapping("/loginUser")
public String loginUserInfo(Model model, @RequestParam("username") String username, @RequestParam("password") String password) {
System.out.println(username+"========"+password);
try {
//构造令牌对象
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
//获取主体对象
Subject subject = SecurityUtils.getSubject();
subject.login(token);//是否登录,转交SecurityManager处理
if(subject.isAuthenticated()){
return "main.html";
}
} catch (UnknownAccountException e) {
model.addAttribute("message","用户名或密码错误");
return "login";
}catch (IncorrectCredentialsException e) {
model.addAttribute("message","用户名或密码错误");
return "login";
}
return null;
}
这是我从自己的练手项目上考下来的 可以直接跑