SSM整合shiro
采用maven构建项目
1pom.xml中加入shiro依赖
<!-- shiro -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.2.1</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-web</artifactId>
<version>1.2.1</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-ehcache</artifactId>
<version>1.2.1</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.2.1</version>
</dependency>
2web.xml中加入shiro过滤器
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1" metadata-complete="true">
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<!-- 定义WEB应用的名字 -->
<display-name>MedicalInsurance</display-name>
<!-- 声明WEB应用的描述信息 -->
<description>北京市医保办</description>
<welcome-file-list>
<welcome-file>/index.jsp</welcome-file>
</welcome-file-list> <!-- 指定Spring配置文件位置 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-*.xml</param-value>
</context-param> <!-- 注册ServletContext监听器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener> <!-- 配置由Spring提供的过滤器,用于整合shiro框架 -->
<!-- 在项目启动的过程中,当前过滤器会从Spring工厂中提取同名对象 -->
<filter>
<filter-name>shiroFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<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> <!-- 注册字符集过滤器 -->
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<!-- 指定字符集编码 -->
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping> <!-- 注册前端控制器 -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping> <!-- Druid监控配置 -->
<servlet>
<servlet-name>DruidStatView</servlet-name>
<servlet-class>com.alibaba.druid.support.http.StatViewServlet</servlet-class>
<init-param>
<!-- 用户名 -->
<param-name>loginUsername</param-name>
<param-value>druid</param-value>
</init-param>
<init-param>
<!-- 密码 -->
<param-name>loginPassword</param-name>
<param-value>druid</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>DruidStatView</servlet-name>
<url-pattern>/druid/*</url-pattern>
</servlet-mapping> </web-app>
3新增shiro配置文件spring-shiro.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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">
<!-- 1. 配置 SecurityManager! -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="cacheManager" ref="cacheManager" />
<property name="authenticator" ref="authenticator"></property>
<!-- 可以配置多个Realm,其实会把realms属性赋值给ModularRealmAuthenticator的realms属性 -->
<property name="realms">
<list>
<ref bean="jdbcRealm" />
<ref bean="secondRealm" />
</list>
</property>
</bean> <!-- 配置 CacheManager.需要加入 ehcache 的 jar 包及配置文件. -->
<bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
<!-- 加载缓存的配置文件 -->
<property name="cacheManagerConfigFile" value="classpath:ehcache.xml" />
</bean> <!--配置自定义realm -->
<bean id="jdbcRealm" class="cn.miye.realm.ShiroRealm">
<!-- 配置密码匹配器 -->
<property name="credentialsMatcher">
<bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
<!-- 加密算法为MD5 -->
<property name="hashAlgorithmName" value="MD5"></property>
<!-- 加密次数 -->
<property name="hashIterations" value="3"></property>
</bean>
</property>
</bean> <bean id="secondRealm" class="cn.miye.realm.SecondRealm">
<property name="credentialsMatcher">
<bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
<property name="hashAlgorithmName" value="SHA1"></property>
<property name="hashIterations" value="3"></property>
</bean>
</property>
</bean>
<!-- 配置认证策略,只要有一个Realm认证成功即可,并且返回所有认证成功信息 -->
<bean id="authenticator" class="org.apache.shiro.authc.pam.ModularRealmAuthenticator">
<property name="authenticationStrategy">
<bean class="org.apache.shiro.authc.pam.AtLeastOneSuccessfulStrategy"></bean>
</property>
</bean>
<!-- 配置 ShiroFilter. id 必须和 web.xml 文件中配置的 DelegatingFilterProxy 的 <filter-name>
一致. 若不一致, 则会抛出: NoSuchBeanDefinitionException. 因为 Shiro 会来 IOC 容器中查找和 <filter-name>
名字对应的 filter bean. -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager" />
<property name="loginUrl" value="/login.jsp" />
<property name="successUrl" value="/list.jsp" />
<property name="unauthorizedUrl" value="/unauthorized.jsp" />
<!-- securityManager:这个属性是必须的。 loginUrl:没有登录的用户请求需要登录的页面时自动跳转到登录页面,不是必须的属性,
不输入地址的话会自动寻找项目web项目的根目录下的”/login.jsp”页面。 successUrl:登录成功默认跳转页面,不配置则跳转至”/”。如果登陆前点击的一个需要登录的页面,
则在登录自动跳转到那个需要登录的页面。不跳转到此。 unauthorizedUrl:没有权限默认跳转的页面。 --> <property name="filterChainDefinitions">
<value>
/login.jsp = anon
/shiro/login = anon
/shiro/logout = logout
/** = authc
</value>
</property> <!-- anon:例子/admins/**=anon 没有参数,表示可以匿名使用。 authc:例如/admins/user/**=authc表示需要认证(登录)才能使用,没有参数
roles:例子/admins/user/**=roles[admin],参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割, 当有多个参数时,例如admins/user/**=roles["admin,guest"],每个参数通过才算通过,相当于hasAllRoles()方法。
perms:例子/admins/user/**=perms[user:add:*],参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,
例如/admins/user/**=perms["user:add:*,user:modify:*"],当有多个参数时必须每个参数都通过才通过,
想当于isPermitedAll()方法。 rest:例子/admins/user/**=rest[user],根据请求的方法,相当于/admins/user/**=perms[user:method]
,其中method为post,get,delete等。 port:例子/admins/user/**=port[8081],当请求的url的端口不是8081是跳转到schemal://serverName:8081?queryString,
其中schmal是协议http或https等,serverName是你访问的host,8081是url配置里port的端口,queryString
是你访问的url里的?后面的参数。 authcBasic:例如/admins/user/**=authcBasic没有参数表示httpBasic认证
ssl:例子/admins/user/**=ssl没有参数,表示安全的url请求,协议为https user:例如/admins/user/**=user没有参数表示必须存在用户,当登入操作时不做检查
注:anon,authcBasic,auchc,user是认证过滤器, perms,roles,ssl,rest,port是授权过滤器 --> </bean> </beans>
4编写自定义的ralm类
package cn.miye.realm; import java.util.HashSet;
import java.util.Set; import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired; import cn.miye.domain.User;
import cn.miye.service.LoginService; public class ShiroRealm extends AuthorizingRealm { @Autowired
private LoginService loginService; @Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
// 把 AuthenticationToken 转换为 UsernamePasswordToken
UsernamePasswordToken upToken = (UsernamePasswordToken) token; // 从 UsernamePasswordToken 中来获取 username
String username = upToken.getUsername(); // 调用数据库的方法, 从数据库中查询 username 对应的用户记录
User user = loginService.queryUser(username); // 若用户不存在, 则可以抛出 UnknownAccountException 异常
if (user == null) {
throw new UnknownAccountException("用户不存在!");
} // 根据用户信息的情况, 决定是否需要抛出其他的 AuthenticationException 异常.
/*
* if("monster".equals(user)){ throw new LockedAccountException("用户被锁定"); }
*/
// 根据用户的情况, 来构建 AuthenticationInfo 对象并返回. 通常使用的实现类为: SimpleAuthenticationInfo
// 1). principal: 认证的实体信息. 可以是 username, 也可以是数据表对应的用户的实体类对象.
Object principal = username;
// 2). credentials: 数据库中密码.
Object credentials = user.getPassword(); // 3). realmName: 当前 realm 对象的 name. 调用父类的 getName() 方法即可
String realmName = getName();
// 4). 盐值.
ByteSource credentialsSalt = ByteSource.Util.bytes(username); SimpleAuthenticationInfo info = null; // new SimpleAuthenticationInfo(principal, credentials, realmName);
info = new SimpleAuthenticationInfo(principal, credentials, credentialsSalt, realmName);
return info;
} // 授权会被 shiro 回调的方法
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
// 1. 从 PrincipalCollection 中来获取登录用户的信息
Object principal = principals.getPrimaryPrincipal(); // 2. 利用登录的用户的信息来用户当前用户的角色或权限(可能需要查询数据库)
Set<String> roles = new HashSet<>();
roles.add("user");
if ("admin".equals(principal)) {
roles.add("admin");
} // 3. 创建 SimpleAuthorizationInfo, 并设置其 reles 属性.
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(roles); // 4. 返回 SimpleAuthorizationInfo 对象.
return info;
}
}
5编写登录controller
package cn.miye.web; import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping; @Controller
@RequestMapping("/shiro")
public class LoginController { @RequestMapping("/login")
public String login(String username, String password) { Subject currentUser = SecurityUtils.getSubject();
// 是否已经登录
if (!currentUser.isAuthenticated()) {
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
// 是否勾选记住我rememberme
token.setRememberMe(true);
try {
// 执行登录.
currentUser.login(token);
}
// 所有认证时异常的父类.
catch (AuthenticationException ae) {
System.out.println("登录失败: " + ae.getMessage());
}
} return "redirect:/list.jsp";
} }
SSM整合shiro的更多相关文章
- ssm整合shiro—实现认证和授权
1.简述 1.1 Apache Shiro是Java的一个安全框架.是一个相对简单的框架,主要功能有认证.授权.加密.会话管理.与Web集成.缓存等. 1.2 Shiro不会去维护用户.维护 ...
- SSM 整合 Shiro
1. 导包 <!-- spring --> <dependency> <groupId>org.springframework</groupId> &l ...
- SSM整合Shiro 身份验证及密码加密简单实现
1.导入maven的相关依赖 <!-- shiro --> <dependency> <groupId>org.apache.shiro</groupId&g ...
- 上手spring boot项目(二)之spring boot整合shiro安全框架
题记:在学习了springboot和thymeleaf之后,想完成一个项目练练手,于是使用springboot+mybatis和thymeleaf完成一个博客系统,在完成的过程中出现的一些问题,将这些 ...
- Spring Boot 整合 Shiro ,两种方式全总结!
在 Spring Boot 中做权限管理,一般来说,主流的方案是 Spring Security ,但是,仅仅从技术角度来说,也可以使用 Shiro. 今天松哥就来和大家聊聊 Spring Boot ...
- Spring Boot2 系列教程(三十二)Spring Boot 整合 Shiro
在 Spring Boot 中做权限管理,一般来说,主流的方案是 Spring Security ,但是,仅仅从技术角度来说,也可以使用 Shiro. 今天松哥就来和大家聊聊 Spring Boot ...
- 一:整合shiro
整合shiro 1.原生的整个 1.1 创建项目 1.2 创建Realm 1.3 配置shiro 2.使用Shiro Starter 2.1 项目创建 2.2 创建Realm 2.3 配置Shiro ...
- SpringMVC整合Shiro权限框架
尊重原创:http://blog.csdn.net/donggua3694857/article/details/52157313 最近在学习Shiro,首先非常感谢开涛大神的<跟我学Shiro ...
- SpringBoot系列十二:SpringBoot整合 Shiro
声明:本文来源于MLDN培训视频的课堂笔记,写在这里只是为了方便查阅. 1.概念:SpringBoot 整合 Shiro 2.具体内容 Shiro 是现在最为流行的权限认证开发框架,与它起名的只有最初 ...
随机推荐
- A Dangerous Maze LightOJ - 1027
这题意真是... 题意:你在一个迷宫里,有一些门,每个门有一个参数x,如果为正表明你进入门后可以花x的时间出去,如果为负表明你进入门后可以花-x的时间回到出发的地方.每次回到出发的地方之后,不能记得之 ...
- 题解报告:hdu 1969 Pie(二分)
Problem Description My birthday is coming up and traditionally I'm serving pie. Not just one pie, no ...
- usb被占用时,可以用这些方法进行adb无线调试
转自: http://www.cnblogs.com/shangdawei/p/4480278.html 可用wifi.网口. 1.先要获取root权限 如果手机没有命令行工具,请先在手机端安装终端模 ...
- Joystick
Joystick相当于5个按键的集合,向上.下.左.右.中间5个方向接通,经常用于游戏场合.
- sleep与wait的对比
链接:https://www.nowcoder.com/questionTerminal/eeff0fdb43034ee7b43838fb9de4519e来源:牛客网 sleep是线程类(Thread ...
- HtmlUnit爬取Ajax动态生成的页面内容
HtmlUnit说白了就是一个浏览器,这个浏览器是用Java写的无界面的浏览器,正因为其没有界面,因此执行的速度还是可以滴. HtmlUnit提供了一系列的API,这些API可以干的功能比较多,如表单 ...
- .NET Core WebAPI Swagger使用
相对于普通的webapi而言,.net core webapi本身并不具备文档的功能,所以可以借助第三方插件:swagger,使用的话很简单. 步骤一. Nuget Packages安装,使用程序包管 ...
- input标签属性
很多时候,我们都用到了很多标签实现输入功能,所以在这里梳理一下. 1.建立一个文本框 <input type="text" name="userName" ...
- asp.net MVC 错误信息“没有为该对象定义无参数的构造函数”请求各位大神帮忙!
在做一个登录的功能,没有用MVC自己生成的identity代码,仿照别人的代码写出了以后出现错误. 错误信息如下: 代码如下: 求各位asp.net大神支招,网上找了资料最终也没解决这个问题.
- Android设计模式——MVP
一.什么是MVP MVP:全称 Model-View-Presenter. MVP框架由3部分组成:View层负责显示,Presenter层负责逻辑处理,Model层提供数据. View:负责绘制UI ...