作者

接前讲,首先针对一个多种用户类型的登录需求,需要先实现多种用户类型的登录界面的展示,Spring Security提供了这样一个接口来帮助我们实现多种用户类型的登录界面的展示,这个接口就是AuthenticationEntryPoint, 实现这样一个接口,我们就可以随心所欲的控制登录界面的展示了,当我们访问一个受权限的资源,而当前又没有权限访问时,Spring Security就会将处理导向这个接口的实现。针对前讲我所提到的需求,在这里我将实现前台用户和后台用户登录界面的展示,先来看看我的源码实现吧,在这里为了实现多用户类型的登录,很多场景我都需要根据相应的请求参数或地址来判断我需要导向哪个URL地址,我在这里特实现了一个共用的接口和类,接口名为DirectUrlResolver。

  1. package com.template.security.shared;
  2. import javax.servlet.http.HttpServletRequest;
  3. /**
  4. * Created by IntelliJ IDEA.
  5. * User: Zhong Gang
  6. * Date: 12-11-9
  7. * Time: 下午7:11
  8. */
  9. public interface DirectUrlResolver {
  10. boolean support(HttpServletRequest request);
  11. String directUrl();
  12. }
  1. package com.template.security.shared;
  2. import javax.servlet.http.HttpServletRequest;
  3. /**
  4. * Created by IntelliJ IDEA.
  5. * User: Zhong Gang
  6. * Date: 12-11-9
  7. * Time: 下午7:12
  8. */
  9. public abstract class AbstractDirectUrlResolver implements DirectUrlResolver {
  10. protected String pattern;
  11. protected String directUrl;
  12. @Override
  13. public abstract boolean support(HttpServletRequest request);
  14. @Override
  15. public String directUrl() {
  16. return this.directUrl;
  17. }
  18. public void setPattern(String pattern) {
  19. this.pattern = pattern;
  20. }
  21. public void setDirectUrl(String directUrl) {
  22. this.directUrl = directUrl;
  23. }
  24. }
  1. package com.template.security.shared;
  2. import com.template.utils.StringUtils;
  3. import javax.servlet.http.HttpServletRequest;
  4. /**
  5. * Created by IntelliJ IDEA.
  6. * User: Zhong Gang
  7. * Date: 12-11-9
  8. * Time: 下午7:13
  9. */
  10. public class RequestParameterDirectUrlResolver extends AbstractDirectUrlResolver {
  11. private String parameterName;
  12. @Override
  13. public boolean support(HttpServletRequest request) {
  14. String parameterValue = request.getParameter(parameterName);
  15. if (StringUtils.isEmpty(parameterValue)) {
  16. return false;
  17. }
  18. return parameterValue.equals(this.pattern);
  19. }
  20. public void setParameterName(String parameterName) {
  21. this.parameterName = parameterName;
  22. }
  23. }
  1. package com.template.security.shared;
  2. import javax.servlet.http.HttpServletRequest;
  3. /**
  4. * Created by IntelliJ IDEA.
  5. * User: Zhong Gang
  6. * Date: 12-11-9
  7. * Time: 下午7:13
  8. */
  9. public class RequestUriDirectUrlResolver extends AbstractDirectUrlResolver {
  10. @Override
  11. public boolean support(HttpServletRequest request) {
  12. String requestURI = request.getRequestURI();
  13. return requestURI.contains(this.pattern);
  14. }
  15. }

RequestParameterDirectUrlResolver和RequestUriDirectUrlResolver都实现了DirectUrlResolver这样一个接口,前者的实现是根据相应请求中的参数来判断, 而后者的实现是根据相应的请求地址来判断。

现在让我们来看看如何通过实现AuthenticationEntryPoint接口来控制什么时候展示前台登录界面,什么时候展示后台登录界面的吧。

  1. package com.template.security.login;
  2. import com.template.security.shared.DirectUrlResolver;
  3. import org.springframework.security.core.AuthenticationException;
  4. import org.springframework.security.web.AuthenticationEntryPoint;
  5. import javax.servlet.ServletException;
  6. import javax.servlet.http.HttpServletRequest;
  7. import javax.servlet.http.HttpServletResponse;
  8. import java.io.IOException;
  9. import java.util.ArrayList;
  10. import java.util.List;
  11. /**
  12. * Created by IntelliJ IDEA.
  13. * User: Zhong Gang
  14. * Date: 12-11-9
  15. * Time: 下午7:40
  16. */
  17. public class MultipleAuthenticationLoginEntry implements AuthenticationEntryPoint {
  18. private String defaultLoginUrl;
  19. private List<DirectUrlResolver> directUrlResolvers = new ArrayList<DirectUrlResolver>();
  20. @Override
  21. public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
  22. for (DirectUrlResolver directUrlResolver : directUrlResolvers) {
  23. if (directUrlResolver.support(request)) {
  24. String loginUrl = directUrlResolver.directUrl();
  25. response.sendRedirect(loginUrl);
  26. return;
  27. }
  28. }
  29. response.sendRedirect(defaultLoginUrl);
  30. }
  31. public void setDefaultLoginUrl(String defaultLoginUrl) {
  32. this.defaultLoginUrl = defaultLoginUrl;
  33. }
  34. public void setDirectUrlResolvers(List<DirectUrlResolver> directUrlResolvers) {
  35. this.directUrlResolvers = directUrlResolvers;
  36. }
  37. }

再来看看在Spring配置文件中是如何对相应的登录入口进行配置的

  1. <beans:bean id="multipleAuthenticationLoginEntry"
  2. class="com.template.security.login.MultipleAuthenticationLoginEntry">
  3. <beans:property name="defaultLoginUrl" value="/backend/login"/>
  4. <beans:property name="directUrlResolvers">
  5. <beans:list>
  6. <beans:ref bean="backendLoginEntry"/>
  7. <beans:ref bean="forendLoginEntry"/>
  8. </beans:list>
  9. </beans:property>
  10. </beans:bean>
  11. <beans:bean id="backendLoginEntry" class="com.template.security.shared.RequestUriDirectUrlResolver">
  12. <beans:property name="pattern" value="/backend"/>
  13. <beans:property name="directUrl" value="/backend/login"/>
  14. </beans:bean>
  15. <beans:bean id="forendLoginEntry" class="com.template.security.shared.RequestUriDirectUrlResolver">
  16. <beans:property name="pattern" value="/forend"/>
  17. <beans:property name="directUrl" value="/forend/login"/>
  18. </beans:bean>

这里我是根据请求的地址中是否包括backend或forend来判断用户是进行前台登录或后台登录的, 这可以从配置文件中的backendLoginEntry和forendLoginEntry中的pattern属性看出,这个pattern的作用就是判断用户是进行前台登录或后台登录的依据,而directUrl则是我们想要导向的登录界面地址。

Spring Security 3多用户登录实现之二 多登录界面展示的更多相关文章

  1. 【手摸手,带你搭建前后端分离商城系统】03 整合Spring Security token 实现方案,完成主业务登录

    [手摸手,带你搭建前后端分离商城系统]03 整合Spring Security token 实现方案,完成主业务登录 上节里面,我们已经将基本的前端 VUE + Element UI 整合到了一起.并 ...

  2. Spring Security笔记:使用BCrypt算法加密存储登录密码

    在前一节使用数据库进行用户认证(form login using database)里,我们学习了如何把“登录帐号.密码”存储在db中,但是密码都是明文存储的,显然不太讲究.这一节将学习如何使用spr ...

  3. Spring Security框架下实现两周内自动登录"记住我"功能

    本文是Spring Security系列中的一篇.在上一篇文章中,我们通过实现UserDetailsService和UserDetails接口,实现了动态的从数据库加载用户.角色.权限相关信息,从而实 ...

  4. Spring Security源码解析一:UsernamePasswordAuthenticationFilter之登录流程

    一.前言 spring security安全框架作为spring系列组件中的一个,被广泛的运用在各项目中,那么spring security在程序中的工作流程是个什么样的呢,它是如何进行一系列的鉴权和 ...

  5. Spring Security构建Rest服务-1001-spring social开发第三方登录之spring social基本原理

    OAuth协议是一个授权协议,目的是让用户在不将服务提供商的用户名密码交给第三方应用的条件下,让第三方应用可以有权限访问用户存在服务提供商上的资源. 接着上一篇说的,在第三方应用获取到用户资源后,如果 ...

  6. Spring Security 实战干货:图解用户是如何登录的

    1. 前言 欢迎阅读Spring Security 实战干货系列文章,在集成Spring Security安全框架的时候我们最先处理的可能就是根据我们项目的实际需要来定制注册登录了,尤其是Http登录 ...

  7. Spring Security构建Rest服务-0102-Spring Social开发第三方登录之qq登录

    图一 基于SpringSocial实现qq登录,要走一个OAuth流程,拿到服务提供商qq返回的用户信息. 由上篇介绍的可知,用户信息被封装在了Connection里,所以最终要拿到Connectio ...

  8. ros有一个比较安全的登录方案:二次登录防火墙

    原文: https://www.winbox.org/ /ip firewall address-list add address=10.0.0.0/8 list=login /ip firewall ...

  9. Spring Security 自定义登录认证(二)

    一.前言 本篇文章将讲述Spring Security自定义登录认证校验用户名.密码,自定义密码加密方式,以及在前后端分离的情况下认证失败或成功处理返回json格式数据 温馨小提示:Spring Se ...

随机推荐

  1. C++构造和解析JSON

    JSON是一种轻量级的数据交互格式,易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率,实际项目中经常用到,相比xml有很多优点,问问度娘,优点一箩筐. 第三方库 json解析选用j ...

  2. a++与++a,谈谈C++的参数传递

    先看一段代码: #include<iostream> using namespace std; void func(int a, int b) { cout << a < ...

  3. flask源码系列

    更新中 HTML文档中元素存在,但是在浏览器中不显示.一般用于配合JavaScript代码使用. 04 LocalStack和Local对象实现栈的管理 05 Flask源码之:配置加载 06 Fla ...

  4. Python进阶(二)----函数参数,作用域

    Python进阶(二)----函数参数,作用域 一丶形参角度:*args,动态位置传参,**kwargs,动态关键字传参 *args: ​ 动态位置参数. 在函数定义时, * 将实参角度的位置参数聚合 ...

  5. Java知识回顾 (13)序列化

    本资料来自于runoob,略有修改. 整个过程都是 Java 虚拟机(JVM)独立的,也就是说,在一个平台上序列化的对象可以在另一个完全不同的平台上反序列化该对象. 类 ObjectInputStre ...

  6. HashMap的内部结构与hash冲突

    HashMap的内部结构 HashMap简介: HashMap继承AbstractMap,AbstractMap实现Map接口 HashMap是线程不同步的,线程不安全的 HashMap可以把null ...

  7. js 数据类型检测

    提起数据类型检测  大多数人首先想起的应该是  typeof 'xxx' == '数据类型' 坦然这种方法对于基本数据类型的检测还是非常方便的,但是当遇到引用数据类型 Object时却爱莫能助,下面就 ...

  8. 关闭linux命令行屏幕保护

    # setterm -blank 0

  9. 机器学习 | 聚类分析总结 & 实战解析

    聚类分析是没有给定划分类别的情况下,根据样本相似度进行样本分组的一种方法,是一种非监督的学习算法.聚类的输入是一组未被标记的样本,聚类根据数据自身的距离或相似度划分为若干组,划分的原则是组内距离最小化 ...

  10. MySQL每天产生了多大容量的binlog,用SQL语句能查到吗?

    首先,这是个假设性命题(又一个钓鱼题). 这个需求完全可以通过系统层命令,配合MySQL中的"FLUSH BINARY LOGS"快速完成. 运行SHOW MASTER/BINAR ...