Spring Security入门(基于SSM环境配置)
一、前期准备
配置
SSM环境
二、不使用数据库进行权限控制
配置好SSM环境以后,配置SpringSecurity环境
添加
security依赖<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>4.1.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>4.1.0.RELEASE</version>
</dependency>在服务器启动该的时候读取
springSecurity配置文件实现方法,通过application域对象实现,和整合
spring和mybatis的方法相同<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:springSecurity.xml
</param-value>
</context-param>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>
org.springframework.web.filter.DelegatingFilterProxy
</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>通过
spring提供的监听器加载security配置文件。使用过滤器链拦截所有的资源,来实现对资源的权限控制
书写
springSecurity配置文件
<security:http>
<security:intercept-url pattern="add" access="hasAuthority('ROLE_USER')" />
<security:intercept-url pattern="index.jsp" access="permitAll()"/>
<security:intercept-url pattern="/login" access="permitAll()"/>
<security:intercept-url pattern="/*" access="isFullyAuthenticated()"/>
<security:form-login login-page="/login" login-processing-url="/login"
authentication-failure-handler-ref="failureHandler"
authentication-success-handler-ref="successHandler">
</security:form-login>
<security:csrf disabled="true"></security:csrf>
</security:http>
<security:authentication-manager>
<security:authentication-provider>
<security:user-service>
<security:user
name="username"
password="username"
authorities="ROLE_USER">
</security:user>
</security:user-service>
</security:authentication-provider>
</security:authentication-manager>
<bean id="successHandler" class="com.bywlstudio.security.SuccessHandler"></bean>
<bean id="failureHandler" class="com.bywlstudio.security.FailureHandler"></bean>
security:http配置权限拦截的方式是基于HTTP的资源拦截方式,有两种
security:form-login基于表单(常用)security默认提供一个登陆界面,可以自定义login-page指定登陆界面(注:用户名的name属性必须为username,密码的name属性必须为password。这是security判断用户输入是否正确的标准)login-processing-url指定登陆界面的表单的提交路径authentication-failure-handler-ref引用一个密码错误以后的处理方式(上面的使用了bean引用)authentication-success-handler-ref应用一个成功以后的处理方式
security:http-basic基本的验证方式(不常用)
secutity:authentication-manager具体的权限管理配置security:intercept-url配置需要拦截的资源access配置可以访问的权限(取值参考:security官方文档)pattern配置需要拦截的资源(上面的资源使用MVC控制)
security:csrf一种浏览器的防护机制,后期文章会详细说明security:authentication-provider具体的实现权限控制security:user配置一个具体的用户authorities配置当前用户所具有的权限,在intercept-url中使用
配置成功和失败的处理器
通过实现
AuthenticationSuccessHandler接口和AuthenticationFailureHandler实现public class FailureHandler implements AuthenticationFailureHandler {
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException e)
throws IOException, ServletException {
response.getWriter().write(WriteStatusJson.loginStatus("status","Failure"));
}
}
public class SuccessHandler implements AuthenticationSuccessHandler {
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
response.getWriter().write(WriteStatusJson.loginStatus("status","success"));
}
}
WriteStatusJson这个类是笔者自定义的一个回状态的工具类,具体实现如下public class WriteStatusJson {
/**
* 返回登陆状态信息
* @param attritute 登陆的状态
* @param value 登陆的成功过或者失败的返回值
* @param <E> 根据每一次状态返回的值而定
* @return {String} 返回一个json字符串
* @throws JsonProcessingException
*/
public static <E> String loginStatus(String attritute , E value)
throws JsonProcessingException {
ObjectMapper objectMapper = new ObjectMapper();
Map<String,E> map = new HashMap<>();
map.put(attritute,value);
return objectMapper.writeValueAsString(map);
}
}主要功能,将需要返回的状态信息转换为字符串(字符串转换使用了
Jackson)
此时一个基本的权限功能已经结束。
三、通过数据库实现权限控制
存在的问题:
用户已经写死,需要增加用户只能通过修改
xml文件。
解决问题的思路
通过
Java代码生成一个User并且赋予它一定的权限引用入一个接口
UserDetailsSevrice重写里面的方法loadUserByUsername方法返回值是一个
UserDetails类型,Spring提供了一个类User实现了UserDetails查看User类的源码
private static final long serialVersionUID = 410L;//序列化
private String password;//密码
private final String username;//用户名
private final Set<GrantedAuthority> authorities;//权限的集合
private final boolean accountNonExpired;//权限是否过期
private final boolean accountNonLocked;//权限是否被锁定
private final boolean credentialsNonExpired;//凭据未过期
private final boolean enabled;//账户可以使用
创建管理用户权限的类
public class UserAuthent implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
User user = new User("MakerStack","love", AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_USER,ROLE_ADMIN"));
return user;
}
}
AuthorityUtils工具类给用户赋予权限,类似于xml中的authorities属性
存在的问题
用户还是写死的,只能用过
spring自带的User对象来赋值,不能连接数据库
解决思路
上面提到
spring自带的User通过实现了UserDetails接口来实现对用户权限的添加自定义
User类实现UserDetails接口,创建操纵User类的持久层接口,获取数据库中的User对象**
具体实现
数据库设计(具体情况具体考虑)
三个表:
用户表。存放具体的用户
角色表。存放对应的角色。(管理员,会员,普通用户)
权限表。存放具体的权限。(增加,删除,修改,查询权限的控制)
每一个用户可以有多个角色,一个角色也可以有多个权限
用户和角色。多对多的关系
角色和权限。多对多的关系
编写数据库表的
ORM映射,编写持久层接口,服务层接口创建实现
UserDetailsService接口的类,实现方法User user = userService.findUserByUsername(username);
if(user!=null){
List<Authority> authorities = userService.findAuthorityByUsername(username);
//需要对user的List<Authority>集合赋值
List<GrantedAuthority> grantedAuthorities = new ArrayList<>();
for (Authority authority : authorities) {
GrantedAuthority grantedAuthority =
new SimpleGrantedAuthority(authority.getTag());
grantedAuthorities.add(grantedAuthority);
}
user.setAuthorities(grantedAuthorities);
}
return user;方法
loadUserByUsername方法的参数即为用户在表单中输入的用户名(后期会出一篇security执行流程的文章,可以关注一下)通过用户名获取对应的用户信息,判断用户是否存在,存在即获取其对应的权限信息;若不存在则直接返回
实体类
User实现了UserDetails接口,内部定义了一个存储用户权限的集合。现在需要做的就是将数据库中的权限信息添加到这个集合中。通过
spring提供的接口GrantedAuthority来实现;通过其子类SimpleGrantedAuthority将数据库中的权限信息写入,赋值给GrantedAuthority类型,添加到一个集合中,将这个集合赋值给user类的权限集合数据库整合完成
需要注意的问题
登陆界面的
name属性必须保证,否则会出现loadUserByUsername方法获取不到参数的问题用户名为
username密码为
password否则
security无法读取
若有读者出现这个错误
Access denied for user 'root'@'localhost'(using password: YES)且你之前连接数据库是正确的,则检查你得数据库配置文件
四、密码加密
目前数据库中存放的密码均为明文传输,所以需要对密码进行加密,而
security提供了为密码加密的算法
步骤
为数据库中的密码加密
通过
security提供的接口PasswordEncoder的实现类BCryptPasswordEncoder实现用户密码的加密和匹配接口
PasswordEncoder中的方法
String encode(CharSequence var1);
boolean matches(CharSequence var1, String var2);实现加密
PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
//哈希算法+变量
String encode = passwordEncoder.encode("123456");
User user = new User();
user.setId(3);
user.setPassword(encode);
userService.updateUserPassword(user);登陆时实现解密
创建
BCryptPasswordEncoder类的bean对象在
<security:authentication-proider>标签中引用
Spring Security入门(基于SSM环境配置)的更多相关文章
- SpringBoot集成Spring Security入门体验
一.前言 Spring Security 和 Apache Shiro 都是安全框架,为Java应用程序提供身份认证和授权. 二者区别 Spring Security:重量级安全框架 Apache S ...
- 030 SSM综合练习06--数据后台管理系统--SSM权限操作及Spring Security入门
1.权限操作涉及的三张表 (1)用户表信息描述users sql语句: CREATE TABLE users ( id ) DEFAULT SYS_GUID () PRIMARY KEY, email ...
- Spring Security 入门(基本使用)
Spring Security 入门(基本使用) 这几天看了下b站关于 spring security 的学习视频,不得不说 spring security 有点复杂,脑袋有点懵懵的,在此整理下学习内 ...
- Spring Security(08)——intercept-url配置
http://elim.iteye.com/blog/2161056 Spring Security(08)--intercept-url配置 博客分类: spring Security Spring ...
- Spring Security 入门详解(转)
1.Spring Security介绍 Spring Security是基于spring的应用程序提供声明式安全保护的安全性框架,它提供了完整的安全性解决方案,能够在web请求级别和方法调用级别 处理 ...
- Spring Security 入门详解
序:本文主要参考 spring实战 对里面的知识做一个梳理 1.Spring Security介绍 Spring Security是基于spring的应用程序提供声明式安全保护的安全性框架,它提供了完 ...
- Spring - IoC(8): 基于 Annotation 的配置
除了基于 XML 的配置外,Spring 也支持基于 Annotation 的配置.Spring 提供以下介个 Annotation 来标注 Spring Bean: @Component:标注一个普 ...
- PHP入门及服务环境配置(Nginx+PHP)
PHP入门及服务环境配置(Nginx+PHP) PHP入门 PHP维基百科: PHP(全称:PHP:Hypertext Preprocessor,即"PHP:超文本预处理器")是一 ...
- Spring Security 入门(1-2)Spring Security - 从 配置例子例子 开始我们的学习历程
1.Spring Security 的配置文件 我们需要为 Spring Security 专门建立一个 Spring 的配置文件,该文件就专门用来作为 Spring Security 的配置. &l ...
随机推荐
- 关于6410板文件的dm9000的平台设备地址
转自csdn #define CONFIG_DM9000_BASE 0x20000300#define DM9000_IO 0x20000000#define ...
- php实现第三方登录
1. oAuth2.0原理 网站为了方便用户快速的登录系统,都会提供使用知名的第三方平台账号进行快速登录的功能,第三方登录都是基于oAuth2.0标准来实现的.下面详细分析[基于账号密码授权]和[基于 ...
- AtCoder Beginner Contest 077 D Small Multiple(最短路)
水过前三道题之后,一直在写这个题,做不对.总有那么几组数据过不去... 看了看题解是最短路,这思路感觉很神奇.看了下唯一做出来这题的那人的代码,是搜索做的. 标程: 对每个数字x,向x+1建一条花费为 ...
- 2019徐州网络赛 I.query
这题挺有意思哈!!!看别人写的博客,感觉瞬间就懂了. 这道题大概题意就是,给一串序列,我们要查找到l-r区间内,满足min(a[ i ],a[ j ]) = gcd(a[ i ],a[ j ]) 其实 ...
- supersocket新的配置属性 "textEncoding"
在 SuperSocket 1.6 之前的版本, 当你通过Session对象发送文本时, 将文本信息转换成能够通过Socket传输的二进制数据的默认编码是UTF8. 你可以通过设置 Session 的 ...
- Laravel 5.6 安装 guzzlehttp
环境:Laravel 5.6 安装 composer require guzzlehttp/guzzle 在vendor文件夹下,vendor\guzzlehttp\guzzle 引入 use Gu ...
- XTU 1236 Fraction
Fraction Accepted : 168 Submit : 1061 Time Limit : 1000 MS Memory Limit : 65536 KB Fraction Prob ...
- pip 指定目录安装
pip install --target=d:\somewhere\other\than\the\default package_name
- Spark1.6.1 MLlib 特征抽取和变换
Spark1.6.1 MLlib 特征抽取和变换 1 TF-IDF TF-IDF是一种特征向量化方法,这种方法多用于文本挖掘,通过算法可以反应出词在语料库中某个文档中的重要性.文档中词记为t,文档记为 ...
- landi pos机
2015年3月:联迪商用获得2014-2015中国金融POS机市场年度成功企业奖: 2014年5月:联迪商用入选2013年福州市纳税百强企业: 2013年12月:联迪商用入选2013年度中国电子商务物 ...