认识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管理权限包括权限.用户请 ...
随机推荐
- VUE004. provide与inject的使用(祖先组件隔多层传静态值给子孙组件)
provide和inject可以通过祖先组件隔三层四层甚至隔着九层妖塔传值给子孙组件. 需要注意的是这样的传值方式是非响应式的,需要结合自身的应用场景,比如将上传的限制条件通过父组件传值给子组件的子组 ...
- Vue设置全局cookies样式
''' 配置全局cookies样式 下载:cnpm install vue-cookies import cookies from 'vue-cookies' Vue.prototype.$cooki ...
- Spring Cloud Eureka 之常用配置解析
[原创内容,转载.引用请注明出处] 1. 配置项解析 1.1 通用配置 # 应用名称,将会显示在Eureka界面的应用名称列 spring.application.name=config-servic ...
- 谈谈如何进阶Java高级工程师
从入门到瓶颈(++文末附学习脑图++) 首先,先自我介绍一下,楼主94年的,四川人,普通大专毕业. 第一阶段 实习阶段 2015年,实习阶段去浙江温州(没错,就是皮革厂的那个地方)找了份软件实施的工作 ...
- Math.round真的是四舍五入吗?我不这么认为
public static long round(double a) 返回最接近参数的 long.结果将舍入为整数:加上 1/2,对结果调用 floor 并将所得结果强制转换为 long 类型.换句话 ...
- minix3使用轻快入门
minix3是一款迷你的unix作业系统,但又不在at&t代码的基础上构建.当年开发这款作业系统的作者仅仅是拿来自用,给学生上课使用的. 如果你已经安装了minix3,你还需要安装openss ...
- git报错:Auto Merge Failed; Fix Conflicts and Then Commit
本文来源:http://blog.csdn.net/trochiluses/article/details/101007191.出错场景: 协同开发时,我们从远程服务器上pull下代码的时候,出现以下 ...
- Orchard Core Framework Samples
解决方案包含内容 多租户应用 一个ASP.NET Core MVC应用程序,它引用模块项目,并为两个启用了不同模块的租户提供支持. 此Web应用程序的主页提供了更多信息,并链接到两个租户和模块端点.租 ...
- Linux系列(13) - CentOs 8 配置静态IP
step-1 vim etho的配置文件 [root#localhost ~]# vim /etc/sysconfig/network-scripts/ifcfg-eth0 step-2 新增修改以下 ...
- Kafka 3.0新特性
1.概述 Kafka是一个分布表示实时数据流平台,可独立部署在单台服务器上,也可部署在多台服务器上构成集群.它提供了发布与订阅的功能,用户可以发送数据到Kafka集群中,也可以从Kafka集群中读取数 ...