在一个系统中认证和授权是常有的事情,现在比较流行的框架有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的更多相关文章

  1. Spring Security OAuth2 开发指南

    官方原文:http://projects.spring.io/spring-security-oauth/docs/oauth2.html 翻译及修改补充:Alex Liao. 转载请注明来源:htt ...

  2. spring mvc 和spring security配置 web.xml设置

    <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmln ...

  3. SPRING SECURITY JAVA配置:Web Security

    在前一篇,我已经介绍了Spring Security Java配置,也概括的介绍了一下这个项目方方面面.在这篇文章中,我们来看一看一个简单的基于web security配置的例子.之后我们再来作更多的 ...

  4. 【OAuth2.0】Spring Security OAuth2.0篇之初识

    不吐不快 因为项目需求开始接触OAuth2.0授权协议.断断续续接触了有两周左右的时间.不得不吐槽的,依然是自己的学习习惯问题,总是着急想了解一切,习惯性地钻牛角尖去理解小的细节,而不是从宏观上去掌握 ...

  5. spring security oauth2.0 实现

    oauth应该属于security的一部分.关于oauth的的相关知识可以查看阮一峰的文章:http://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html ...

  6. Spring Security(08)——intercept-url配置

    http://elim.iteye.com/blog/2161056 Spring Security(08)--intercept-url配置 博客分类: spring Security Spring ...

  7. Spring Security控制权限

    Spring Security控制权限 1,配置过滤器 为了在项目中使用Spring Security控制权限,首先要在web.xml中配置过滤器,这样我们就可以控制对这个项目的每个请求了. < ...

  8. Spring Security笔记:Hello World

    本文演示了Spring Security的最最基本用法,二个页面(或理解成二个url),一个需要登录认证后才能访问(比如:../admin/),一个可匿名访问(比如:../welcome) 注:以下内 ...

  9. Spring Security笔记:自定义Login/Logout Filter、AuthenticationProvider、AuthenticationToken

    在前面的学习中,配置文件中的<http>...</http>都是采用的auto-config="true"这种自动配置模式,根据Spring Securit ...

  10. spring session 和 spring security整合

    背景: 我要做的系统前面放置zuul. 使用自己公司提供的单点登录服务.后面的业务应用也是spring boot支撑的rest服务. 目标: 使用spring security管理权限包括权限.用户请 ...

随机推荐

  1. 使用Dockerfile Maven插件

    我们常见开源项目中使用的Docker Maven插件是com.spotify:docker-maven-plugin.可用版本信息见Github. 通过其介绍可知该插件已经不再推荐使用,取而代之的是c ...

  2. Linux系列(24) - chmod

    前言 在Unix和Linux的中,每个文件(文件夹也被看作是文件)都有三种权限:读.写.运行. 被授予权限的用户身份有三种:当前文件的拥有者,与拥有者属于同组者(同一个group),其他人 hello ...

  3. 关于web桌面应用的集成解决方案

    背景 毫无疑问,面对一个新的项目需求,我们首先想到的就是web. 确实,web太方便了,基于浏览器对OS的适配,我们可以很快速的实现某个需求的页面UI,而无需考虑OS的兼容差异. 再经过jq.boot ...

  4. javascript Date 日期格式化 formatDate, require.js 模块 支持全局js引入 / amd方式加载

    * 引入AMD加载方式: require.js CDN https://cdn.bootcss.com/require.js/2.3.5/require.js *  创建模块文件./js/util/d ...

  5. pyqt5设计无边框窗口(一)

    import sys from PyQt5 import QtGui,QtCore from PyQt5 import QtCore, QtGui, QtWidgets ############### ...

  6. 『Python』matplotlib的imshow用法

    热力图是一种数据的图形化表示,具体而言,就是将二维数组中的元素用颜色表示.热力图之所以非常有用,是因为它能够从整体视角上展示数据,更确切的说是数值型数据. 使用imshow()函数可以非常容易地制作热 ...

  7. CF1556D-Take a Guess【交互】

    正题 题目链接:https://codeforces.com/contest/1556/problem/D 题目大意 现在有\(n\)个你不知道的数字,你有两种询问操作 询问两个下标的数字的\(and ...

  8. Redis高可用解决方案:哨兵(Sentinel)

    哨兵是Redis的高可用解决方案:由多个哨兵组成的系统监视主从服务器,可以将下线的主服务器属下的某个从服 务器升级为新的主服务器,继续保障运行. 启动并初始化Sentinel redis-sentin ...

  9. SDOI2015 排序

    SDOI2015 排序 今天看到这道题,没有一点思路,暴力都没的打...还是理解错题意了,操作不同位置不是说改不同的区间,而是不同操作的顺序...考场上如果知道这个的话最少暴力拿一半啊,因为正解本来就 ...

  10. mysql-router-MIC-8.0.26集群部署

    1.具体部署详情请看视频 https://space.bilibili.com/677825194 2.mysql主要配置如下 cat > /etc/my.cnf <<EOF [cl ...