认识spring security
在一个系统中认证和授权是常有的事情,现在比较流行的框架有spring security、shiro等等。他们都能很好的帮助我们完成认证和授权的功能。那么假如说让我们自己完成一个登录那么应该大致的流程是怎么样的呢?
一、我们肯定有一个处理页面上表单提交的url处理器,此处我们放置在Filter中进行处理,假如就叫做UsernamePasswordAuthenticationFilter ,在这个Filter里面我们需要将用户提交上来的用户名和密码封装成一个对象,假如叫做UsernamePasswordAuthenticationToken。
二、有了上一步的 UsernamePasswordAuthenticationToken 之后,我们肯定要对这个token进行一个认证,那UsernamePasswordAuthenticationFilter中就必须要有一个认证管理器(AuthenticationManager),来处理我们这个token的认证。
三、有了认证管理器后,那这个认证管理器可能可以处理多种方式的登录,比如基于ip地址的登录、基于用户名和密码的登录、基于remember me(记住我)的登录等等。那么在我们的认证管理器的实现中(ProviderManager)就应该存在一组AuthenticationProvider,每个AuthenticationProvider处理不同的Token认证。
比如:DaoAuthenticationProvider用于处理UsernamePasswordAuthenticationToken
RememberMeAuthenticationProvider用于处理RememberMeAuthenticationToken
四、当我们是基于用户名和密码登录认证时,那么对应的AuthenticationProvider就是DaoAuthenticationProvider, 那么我们肯定有一个接口根据用户输入的用户名返回一个用户对象即 UserDetailsService#loadUserByUsername(String) 接口,返回一个UserDetails 对象,有了用户对象后,我们系统中密码肯定是加密过的,那么就必须还要一个密码加密器PasswordEncoder,用于进行密码的校验。
五、当完成上面的认证后
成功认证:那么肯定有一个成功后的回调,加入是 AuthenticationFailureHandler , 在这个里面我们可以完成成功后页面的跳转
认证失败:也有一个失败的回调,假如是 AuthenticationFailureHandler,可以记录失败的日志,完成失败后的跳转
有了上面的初步认识后,我们来看一下在spring security中是如何做的。
一、引入spring security的pom配置文件
<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.spring.platform</groupId>
<artifactId>platform-bom</artifactId>
<version>Brussels-SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
二、进行spring security的配置
/**
* spring security 的配置
*
* @描述
* @作者 huan
* @时间 2017年11月1日 - 下午9:33:59
*/
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(createUserDetailService())//
.passwordEncoder(passwordEncoder())//
.and()//
.inMemoryAuthentication()//
.withUser("admin")
.password("admin")
.roles("ADMIN");// 配置一个拥有用户名和密码的用户
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.formLogin() // 表单登录
.loginProcessingUrl("/login")// 处理登录的请求
.loginPage("/login.html") // 自定义登录界面
.usernameParameter("authUsername")//登录表单的用户名的name的值
.passwordParameter("authPassword")//登录表单密码的name的值
.successHandler(securityAuthenticationSuccessHandler())// 认证成功后的处理
.failureHandler(securityAuthenticationFailureHandler()) // 认证失败后的处理
.and()//
.userDetailsService(createUserDetailService()) // 用户服务,根据用户名加载用户信息
.logout() // 登出
.logoutUrl("/logout") // 登出的url路径
.addLogoutHandler(securityLogoutHandler())//登出时的处理操作
.clearAuthentication(true)// 清除认证
.invalidateHttpSession(true)// session失效
.and()//
.csrf() // csrf
.disable()//
.authorizeRequests()//
.antMatchers("/login.html","/login").permitAll() // 可匿名访问
.anyRequest().authenticated() // 除了上方的请求,其余的请求需要认证才可以访问
.and()//
.exceptionHandling()//
.accessDeniedPage("/403.html"); // 没有权限访问的页面
}
@Bean
public AuthenticationFailureHandler securityAuthenticationFailureHandler() {
SecurityAuthenticationFailureHandler authenticationFailureHandler = new SecurityAuthenticationFailureHandler();
authenticationFailureHandler.setDefaultFailureUrl("/login.html?error");
return authenticationFailureHandler;
}
@Bean
public AuthenticationSuccessHandler securityAuthenticationSuccessHandler() {
SecurityAuthenticationSuccessHandler authenticationSuccessHandler = new SecurityAuthenticationSuccessHandler();
authenticationSuccessHandler.setAlwaysUseDefaultTargetUrl(true);
authenticationSuccessHandler.setDefaultTargetUrl("/index.html");
return authenticationSuccessHandler;
}
@Bean
public LogoutHandler securityLogoutHandler() {
return new SecurityLogoutHandler();
}
@Bean
public UserDetailsService createUserDetailService() {
return new SecurityUserDetailServiceImpl(passwordEncoder());
}
/** 密码加密器 */
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
三、各个实体类
四、登录页
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>用户登录</title>
</head>
<body>
<form action="/login" method="post">
用户名:<input type="text" name="authUsername" /><br />
密码:<input type="password" name="authPassword" /><br/>
<input type="submit" value="登录">
</form>
</body>
</html>
五、首页
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>首页</title>
<link rel="stylesheet" type="text/css" href="/static/css/index.css">
</head>
<body>
<h1>
登录成功。<a href="/logout">退出</a>
</h1>
</body>
</html>
六、界面效果
登录页
登录成功后的首页
认识spring security的更多相关文章
- Spring Security OAuth2 开发指南
官方原文:http://projects.spring.io/spring-security-oauth/docs/oauth2.html 翻译及修改补充:Alex Liao. 转载请注明来源:htt ...
- spring mvc 和spring security配置 web.xml设置
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmln ...
- SPRING SECURITY JAVA配置:Web Security
在前一篇,我已经介绍了Spring Security Java配置,也概括的介绍了一下这个项目方方面面.在这篇文章中,我们来看一看一个简单的基于web security配置的例子.之后我们再来作更多的 ...
- 【OAuth2.0】Spring Security OAuth2.0篇之初识
不吐不快 因为项目需求开始接触OAuth2.0授权协议.断断续续接触了有两周左右的时间.不得不吐槽的,依然是自己的学习习惯问题,总是着急想了解一切,习惯性地钻牛角尖去理解小的细节,而不是从宏观上去掌握 ...
- spring security oauth2.0 实现
oauth应该属于security的一部分.关于oauth的的相关知识可以查看阮一峰的文章:http://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html ...
- Spring Security(08)——intercept-url配置
http://elim.iteye.com/blog/2161056 Spring Security(08)--intercept-url配置 博客分类: spring Security Spring ...
- Spring Security控制权限
Spring Security控制权限 1,配置过滤器 为了在项目中使用Spring Security控制权限,首先要在web.xml中配置过滤器,这样我们就可以控制对这个项目的每个请求了. < ...
- Spring Security笔记:Hello World
本文演示了Spring Security的最最基本用法,二个页面(或理解成二个url),一个需要登录认证后才能访问(比如:../admin/),一个可匿名访问(比如:../welcome) 注:以下内 ...
- Spring Security笔记:自定义Login/Logout Filter、AuthenticationProvider、AuthenticationToken
在前面的学习中,配置文件中的<http>...</http>都是采用的auto-config="true"这种自动配置模式,根据Spring Securit ...
- spring session 和 spring security整合
背景: 我要做的系统前面放置zuul. 使用自己公司提供的单点登录服务.后面的业务应用也是spring boot支撑的rest服务. 目标: 使用spring security管理权限包括权限.用户请 ...
随机推荐
- 浅谈KMP模式匹配算法
普通的模式匹配算法(BF算法) 子串的定位操作通常称为模式匹配算法 假设有一个需求,需要我们从串"a b a b c a b c a c b a b"中,寻找内容为"a ...
- python模块--pathlib
类/属性/方法 返回值 参数 说明 .Path() p 创建Path对象 path 路径 p.parent Path 返回上一级路径 p.parents iter 上一级路径, 上上级 ...
- go相关
mac 上build go 如果想要在centos上面执行 必须使用下面的方式 CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -o hello ...
- Docker 网络类型
Docker 网络类型 前言 a. 本文主要为 Docker的视频教程 笔记. b. 环境为 CentOS 7.0 云服务器 c. 上一篇:docker-compose 的使用和负载均衡的初探 1. ...
- 【简单数据结构】链表--洛谷P1160
题目描述 一个学校里老师要将班上NN个同学排成一列,同学被编号为1\sim N1∼N,他采取如下的方法: 先将11号同学安排进队列,这时队列中只有他一个人: 2-N2−N号同学依次入列,编号为i的同学 ...
- Loadrunner拼装唯一值方法
由于Loadrunner函数有限性,唯一值需要几个函数的字符串进行拼装,可实现流水号.订单号等等数值的唯一性.具体可见下列方法: 方法一: char OraderID[15];srand(time{N ...
- mysql5.7执行sql语句提示Expression #1 of ORDER BY clause is not in GROUP BY
mysql 新版本出现group by 语句不兼容问题 [Err] 1055 - Expression #1 of ORDER BY clause is not in GROUP BY clause ...
- requests接口测试-requests的安装
requests接口测试-requests的安装 安装常见问题 提示连接不上,443问题 一般是因为浏览器设置了代理,关闭代理. 网络加载慢,设置国内镜像地址 1.pip安装 2.pycharm安装 ...
- python学习笔记(十六)-Python多线程多进程
一.线程&进程 对于操作系统来说,一个任务就是一个进程(Process),比如打开一个浏览器就是启动一个浏览器进程,打开一个记事本就启动了一个记事本进程,打开两个记事本就启动了两个记事本进程, ...
- JDBC封装的工具类
1. JDBC封装的工具类 public class JDBCUtil { private static Properties p = new Properties(); private static ...