Spring Security(三十二):10. Core Services
Now that we have a high-level overview of the Spring Security architecture and its core classes, let’s take a closer look at one or two of the core interfaces and their implementations, in particular the AuthenticationManager
, UserDetailsService
and the AccessDecisionManager
. These crop up regularly throughout the remainder of this document so it’s important you know how they are configured and how they operate.
10.1 The AuthenticationManager, ProviderManager and AuthenticationProvider
The AuthenticationManager
is just an interface, so the implementation can be anything we choose, but how does it work in practice? What if we need to check multiple authentication databases or a combination of different authentication services such as a database and an LDAP server?
ProviderManager
and rather than handling the authentication request itself, it delegates to a list of configured AuthenticationProvider
s, each of which is queried in turn to see if it can perform the authentication. Each provider will either throw an exception or return a fully populated Authentication
object. Remember our good friends, UserDetails
and UserDetailsService
? If not, head back to the previous chapter and refresh your memory. The most common approach to verifying an authentication request is to load the corresponding UserDetails
and check the loaded password against the one that has been entered by the user. This is the approach used by the DaoAuthenticationProvider
(see below). The loaded UserDetails
object - and particularly the GrantedAuthority
s it contains - will be used when building the fully populated Authentication
object which is returned from a successful authentication and stored in the SecurityContext
.ProviderManager
is created and maintained internally, and you add providers to it by using the namespace authentication provider elements (see the namespace chapter). In this case, you should not declare a ProviderManager
bean in your application context. However, if you are not using the namespace then you would declare it like so:<bean id="authenticationManager"
class="org.springframework.security.authentication.ProviderManager">
<constructor-arg>
<list>
<ref local="daoAuthenticationProvider"/>
<ref local="anonymousAuthenticationProvider"/>
<ref local="ldapAuthenticationProvider"/>
</list>
</constructor-arg>
</bean>
In the above example we have three providers. They are tried in the order shown (which is implied by the use of a List
), with each provider able to attempt authentication, or skip authentication by simply returning null
. If all implementations return null, the ProviderManager
will throw a ProviderNotFoundException
. If you’re interested in learning more about chaining providers, please refer to the ProviderManager
Javadoc.
ProviderManager
and will call it to handle their authentication requests. The providers you require will sometimes be interchangeable with the authentication mechanisms, while at other times they will depend on a specific authentication mechanism. For example, DaoAuthenticationProvider
and LdapAuthenticationProvider
are compatible with any mechanism which submits a simple username/password authentication request and so will work with form-based logins or HTTP Basic authentication. AuthenticationProvider
. An example of this would be JA-SIG CAS, which uses the notion of a service ticket and so can therefore only be authenticated by a CasAuthenticationProvider
. You needn’t be too concerned about this, because if you forget to register a suitable provider, you’ll simply receive a ProviderNotFoundException
when an attempt to authenticate is made.10.1.1 Erasing Credentials on Successful Authentication
By default (from Spring Security 3.1 onwards) the ProviderManager
will attempt to clear any sensitive credentials information from the Authentication
object which is returned by a successful authentication request. This prevents information like passwords being retained longer than necessary.
Authentication
contains a reference to an object in the cache (such as a UserDetails
instance) and this has its credentials removed, then it will no longer be possible to authenticate against the cached value. You need to take this into account if you are using a cache. An obvious solution is to make a copy of the object first, either in the cache implementation or in the AuthenticationProvider
which creates the returned Authentication
object. Alternatively, you can disable the eraseCredentialsAfterAuthentication
property on ProviderManager
. See the Javadoc for more information.10.1.2 DaoAuthenticationProvider
The simplest AuthenticationProvider
implemented by Spring Security is DaoAuthenticationProvider
, which is also one of the earliest supported by the framework. It leverages a UserDetailsService
(as a DAO) in order to lookup the username, password and GrantedAuthority
s. It authenticates the user simply by comparing the password submitted in a UsernamePasswordAuthenticationToken
against the one loaded by the UserDetailsService
. Configuring the provider is quite simple:
<bean id="daoAuthenticationProvider"
class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
<property name="userDetailsService" ref="inMemoryDaoImpl"/>
<property name="passwordEncoder" ref="passwordEncoder"/>
</bean>
The PasswordEncoder
is optional. A PasswordEncoder
provides encoding and decoding of passwords presented in the UserDetails
object that is returned from the configured UserDetailsService
. This will be discussed in more detail below.
10.2 UserDetailsService Implementations
As mentioned in the earlier in this reference guide, most authentication providers take advantage of the UserDetails
and UserDetailsService
interfaces. Recall that the contract for UserDetailsService
is a single method:
UserDetails loadUserByUsername(String username) throws UsernameNotFoundException;
The returned UserDetails
is an interface that provides getters that guarantee non-null provision of authentication information such as the username, password, granted authorities and whether the user account is enabled or disabled. Most authentication providers will use a UserDetailsService
, even if the username and password are not actually used as part of the authentication decision. They may use the returned UserDetails
object just for its GrantedAuthority
information, because some other system (like LDAP or X.509 or CAS etc) has undertaken the responsibility of actually validating the credentials.
UserDetailsService
is so simple to implement, it should be easy for users to retrieve authentication information using a persistence strategy of their choice. Having said that, Spring Security does include a couple of useful base implementations, which we’ll look at below.10.2.1 In-Memory Authentication
Is easy to use create a custom UserDetailsService
implementation that extracts information from a persistence engine of choice, but many applications do not require such complexity. This is particularly true if you’re building a prototype application or just starting integrating Spring Security, when you don’t really want to spend time configuring databases or writing UserDetailsService
implementations. For this sort of situation, a simple option is to use the user-service
element from the security namespace:
<user-service id="userDetailsService">
<user name="jimi" password="jimispassword" authorities="ROLE_USER, ROLE_ADMIN" />
<user name="bob" password="bobspassword" authorities="ROLE_USER" />
</user-service>
This also supports the use of an external properties file:
<user-service id="userDetailsService" properties="users.properties"/>
The properties file should contain entries in the form
username=password,grantedAuthority[,grantedAuthority][,enabled|disabled]
For example
jimi=jimispassword,ROLE_USER,ROLE_ADMIN,enabled
bob=bobspassword,ROLE_USER,enabled
10.2.2 JdbcDaoImpl
Spring Security also includes a UserDetailsService
that can obtain authentication information from a JDBC data source. Internally Spring JDBC is used, so it avoids the complexity of a fully-featured object relational mapper (ORM) just to store user details. If your application does use an ORM tool, you might prefer to write a custom UserDetailsService
to reuse the mapping files you’ve probably already created. Returning to JdbcDaoImpl
, an example configuration is shown below:
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
<property name="url" value="jdbc:hsqldb:hsql://localhost:9001"/>
<property name="username" value="sa"/>
<property name="password" value=""/>
</bean> <bean id="userDetailsService"
class="org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl">
<property name="dataSource" ref="dataSource"/>
</bean>
You can use different relational database management systems by modifying the DriverManagerDataSource
shown above. You can also use a global data source obtained from JNDI, as with any other Spring configuration.
Authority Groups
By default, JdbcDaoImpl
loads the authorities for a single user with the assumption that the authorities are mapped directly to users (see the database schema appendix). An alternative approach is to partition the authorities into groups and assign groups to the user. Some people prefer this approach as a means of administering user rights. See the JdbcDaoImpl
Javadoc for more information on how to enable the use of group authorities. The group schema is also included in the appendix.
Spring Security(三十二):10. Core Services的更多相关文章
- Spring Security(十二):5. Java Configuration
General support for Java Configuration was added to Spring Framework in Spring 3.1. Since Spring Sec ...
- 精选Spring Boot三十五道必知必会知识点
Spring Boot 是微服务中最好的 Java 框架. 我们建议你能够成为一名 Spring Boot 的专家.本文精选了三十五个常见的Spring Boot知识点,祝你一臂之力! 问题一 Spr ...
- Java进阶(三十二) HttpClient使用详解
Java进阶(三十二) HttpClient使用详解 Http协议的重要性相信不用我多说了,HttpClient相比传统JDK自带的URLConnection,增加了易用性和灵活性(具体区别,日后我们 ...
- Spring Cloud(十二):分布式链路跟踪 Sleuth 与 Zipkin【Finchley 版】
Spring Cloud(十二):分布式链路跟踪 Sleuth 与 Zipkin[Finchley 版] 发表于 2018-04-24 | 随着业务发展,系统拆分导致系统调用链路愈发复杂一个前端请 ...
- [转]Spring Security学习总结二
原文链接: http://www.blogjava.net/redhatlinux/archive/2008/08/20/223148.html http://www.blogjava.net/red ...
- COJ968 WZJ的数据结构(负三十二)
WZJ的数据结构(负三十二) 难度级别:D: 运行时间限制:5000ms: 运行空间限制:262144KB: 代码长度限制:2000000B 试题描述 给你一棵N个点的无根树,边上均有权值,每个点上有 ...
- NeHe OpenGL教程 第三十二课:拾取游戏
转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...
- “全栈2019”Java多线程第三十二章:显式锁Lock等待唤醒机制详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...
- ASP 三十二条精华代码 (1)
ASP 三十二条精华代码 (1) 2009-08-10 09:53:03 www.hackbase.com 来源:互联网 1. oncontextmenu="window.event.r ...
- “全栈2019”Java第三十二章:增强for循环Foreach语法
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...
随机推荐
- synchronized底层实现学习
上文我们总结了 synchronized 关键字的基本用法以及作用,并未涉及 synchronized 底层是如何实现的,所谓刨根问底,本文我们就开始 synchronized 原理的探索之旅吧(*& ...
- Linux下的C#连接Mysql数据库
今天在尝试在 Linux 系统下使用C#连接数据库,发现网上这方面的信息很少,所以就写一篇博客记录一下. Linux下这里使用的是mono. 首先是缺少Mysql.Data.dll这个库的,所以需要安 ...
- kubernetes系列05—kubectl应用快速入门
本文收录在容器技术学习系列文章总目录 1.使用kubectl 1.1 介绍 kubectl用于运行Kubernetes集群命令的管理工具. 1.2 语法 kubectl [command] [TYPE ...
- 应用集成mycat,实现mycat的高可用与mysql的读写分离
前言 开心一刻 一个女人自朋友圈写道:我家老公昨天和别人家的老婆出去旅游,迄今未归,我则被别人家的老公折腾了一天,好累哦! 圈子下面,评论无数,老公在下面评论到:能不能好好说话,我只不过陪女儿去毕业旅 ...
- 【Zabbix】Zabbix Server自动发现
Zabbix自动发现 由于有上百台的虚拟机需要监控,如果一个个去添加配置,费时费力.Zabbix的自动发现,可以自动发现需要监控的机器,监控相应指标. 前置条件 安装部署好Zabbix Server. ...
- frame buffer简单应用
现在我们要在LCD上画一个点,我们无法直接对LCD屏进行操作.这时候就需要用到FrameBuffer,Linux可以FrameBuffer这个设备来供用户态进程实现直接写屏.首先我们先简单看一下lin ...
- 商汤科技汤晓鸥:其实不存在AI行业,唯一存在的是“AI+“行业
https://mp.weixin.qq.com/s/bU-TFh8lBAF5L0JrWEGgUQ 9 月 17 日,2018 世界人工智能大会在上海召开,在上午主论坛大会上,商汤科技联合创始人汤晓鸥 ...
- C# MessageBox自动关闭
本文以一个简单的小例子,介绍如何让MessageBox弹出的对话框,在几秒钟内自动关闭.特别是一些第三方插件(如:dll)弹出的对话框,最为适用.本文仅供学习分享使用,如有不足之处,还请指正. 概述 ...
- python集合使用范例的代码
在代码过程中中,将代码过程中比较好的代码段珍藏起来,如下的代码是关于python集合使用范例的代码,希望能对大伙有用. # sets are unordered collections of uniq ...
- 商家APP店内点餐开启有桌台点餐模式
商家APP店内点餐开启有桌台点餐模式 步骤一:管理员后台-配置管理--店铺配置--简易付tab页--是否支持扫码下单-是 步骤二:管理员后台-配置管理--设备管理--选择对应的机器--配置--云POS ...