spring security 3.0 实现认证与授权
先看一下spring security 官方对以下几个类或接口的解释,因为这个几个类在程序中会使用到;
ConfigAttribute:Stores a security system related configuration attribute.
SecurityConfig:ConfigAttribute的实现类。
GrantedAuthority:Represents an authority granted to an Authentication object.
GrantedAuthorityImpl:GrantedAuthority的实现类。
UserDetails:Provides core user information.
Authentication:Represents the token for an authentication request or for an authenticated principal once the request has been processed by the AuthenticationManager.authenticate(Authentication) method.
UserDetailsService:Core interface which loads user-specific data.
FilterInvocationSecurityMetadataSource:Marker interface for SecurityMetadataSource implementations that are designed to perform lookups keyed on FilterInvocations.
AccessDecisionManager:Makes a final access control (authorization) decision.
?
定义四张表:用户表、角色表、资源表、组织机构表(可选)
?
首先需要在web.xml文件中添加以下配置:
?
接着需要写一个类实现UserDetails接口,这个并不是我们系统的用户,它只是一个VO,
用于保存从spring security上下文环境中获取到登录用户,因为从spring security上下文环境中获取登录用户的返回值就是UserDetails的实现类:package xxx.xxx.xxx.commons.permissionengine.web.security;import java.util.Collection;import java.util.Iterator;import org.springframework.security.access.AccessDecisionManager;import org.springframework.security.access.AccessDeniedException;import org.springframework.security.access.ConfigAttribute;import org.springframework.security.access.SecurityConfig;import org.springframework.security.authentication.InsufficientAuthenticationException;import org.springframework.security.core.Authentication;import org.springframework.security.core.GrantedAuthority;/** * 决策管理器,用于判断用户需要访问的资源与用户所拥有的角色是否匹配 * @author Keven * */public class SecurityAccessDecisionManager implements AccessDecisionManager {@Overridepublic void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException {if(configAttributes == null)return;//获取资源与角色对应关系列表Iterator<ConfigAttribute> iter = configAttributes.iterator();while(iter.hasNext()) {ConfigAttribute configAttribute = iter.next();//获取访问该资源需要的角色String needRole = ((SecurityConfig)configAttribute).getAttribute();//从上下文环境获取用户所具有的角色for(GrantedAuthority grantedAuthority : authentication.getAuthorities()) {//判断用户拥有的角色是否与访问该资源所需要的角色匹配if(needRole.equals(grantedAuthority.getAuthority()))return;}}throw new AccessDeniedException("权限不足!");}@Overridepublic boolean supports(ConfigAttribute arg0) {return true;}@Overridepublic boolean supports(Class<?> arg0) {return true;}}?spring security的基本的登录认证和授权就这样完成了,有关spring security的方法和领域对象的权限控制、单点登录和分布式登录请看下集。
1 楼 stevensinclair 2011-07-10 为什么要这么麻烦去自定义过滤器呢 你要处理URL的话,每个URL就是一个菜单,你系统肯定有菜单管理的,通过菜单管理,把菜单赋予角色 角色赋予用户就能搞定了。你觉得呢? 2 楼 gaowenming 2011-07-10 stevensinclair 写道为什么要这么麻烦去自定义过滤器呢 你要处理URL的话,每个URL就是一个菜单,你系统肯定有菜单管理的,通过菜单管理,把菜单赋予角色 角色赋予用户就能搞定了。你觉得呢?
要是只过滤菜单的话其实是不安全的,菜单里面的url要是被人知道的也可以访问,所以控制菜单不是绝对的安全。 3 楼 bh三少 2011-07-10 gaowenming 写道stevensinclair 写道为什么要这么麻烦去自定义过滤器呢 你要处理URL的话,每个URL就是一个菜单,你系统肯定有菜单管理的,通过菜单管理,把菜单赋予角色 角色赋予用户就能搞定了。你觉得呢?
要是只过滤菜单的话其实是不安全的,菜单里面的url要是被人知道的也可以访问,所以控制菜单不是绝对的安全。
对~这里面已经包含了访问控制 4 楼 stevensinclair 2011-07-11 gaowenming 写道stevensinclair 写道为什么要这么麻烦去自定义过滤器呢 你要处理URL的话,每个URL就是一个菜单,你系统肯定有菜单管理的,通过菜单管理,把菜单赋予角色 角色赋予用户就能搞定了。你觉得呢?
要是只过滤菜单的话其实是不安全的,菜单里面的url要是被人知道的也可以访问,所以控制菜单不是绝对的安全。
菜单是赋值给有这个链接地址权限的用户的,那么是不存在你说的这个问题了。
说白了 我说的菜单就是url,但最终用户知道的只是菜单。
你觉得呢? 5 楼 stevensinclair 2011-07-11 stevensinclair 写道gaowenming 写道stevensinclair 写道为什么要这么麻烦去自定义过滤器呢 你要处理URL的话,每个URL就是一个菜单,你系统肯定有菜单管理的,通过菜单管理,把菜单赋予角色 角色赋予用户就能搞定了。你觉得呢?
要是只过滤菜单的话其实是不安全的,菜单里面的url要是被人知道的也可以访问,所以控制菜单不是绝对的安全。
菜单是赋值给有这个链接地址权限的用户的,那么是不存在你说的这个问题了。
说白了 我说的菜单就是url,但最终用户知道的只是菜单。
你觉得呢?
补充:在你的上下文里面是存在是否具有这个authority的逻辑的, 如果用户直接访问地址,访问被拒绝。 6 楼 bh三少 2011-07-11 stevensinclair 写道stevensinclair 写道gaowenming 写道stevensinclair 写道为什么要这么麻烦去自定义过滤器呢 你要处理URL的话,每个URL就是一个菜单,你系统肯定有菜单管理的,通过菜单管理,把菜单赋予角色 角色赋予用户就能搞定了。你觉得呢?
要是只过滤菜单的话其实是不安全的,菜单里面的url要是被人知道的也可以访问,所以控制菜单不是绝对的安全。
菜单是赋值给有这个链接地址权限的用户的,那么是不存在你说的这个问题了。
说白了 我说的菜单就是url,但最终用户知道的只是菜单。
你觉得呢?
补充:在你的上下文里面是存在是否具有这个authority的逻辑的, 如果用户直接访问地址,访问被拒绝。
肯定存在,不存在就没法做到访问控制。 7 楼 stevensinclair 2011-07-14 bh三少 写道stevensinclair 写道stevensinclair 写道gaowenming 写道stevensinclair 写道为什么要这么麻烦去自定义过滤器呢 你要处理URL的话,每个URL就是一个菜单,你系统肯定有菜单管理的,通过菜单管理,把菜单赋予角色 角色赋予用户就能搞定了。你觉得呢?
要是只过滤菜单的话其实是不安全的,菜单里面的url要是被人知道的也可以访问,所以控制菜单不是绝对的安全。
菜单是赋值给有这个链接地址权限的用户的,那么是不存在你说的这个问题了。
说白了 我说的菜单就是url,但最终用户知道的只是菜单。
你觉得呢?
补充:在你的上下文里面是存在是否具有这个authority的逻辑的, 如果用户直接访问地址,访问被拒绝。
肯定存在,不存在就没法做到访问控制。
你的安全元数据里面的构造函数逻辑是去数据库把角色对应的资源全部加载到内存,那现在数据量很大,速度很慢怎么办?
8 楼 stevensinclair 2011-07-14 stevensinclair 写道bh三少 写道stevensinclair 写道stevensinclair 写道gaowenming 写道stevensinclair 写道为什么要这么麻烦去自定义过滤器呢 你要处理URL的话,每个URL就是一个菜单,你系统肯定有菜单管理的,通过菜单管理,把菜单赋予角色 角色赋予用户就能搞定了。你觉得呢?
要是只过滤菜单的话其实是不安全的,菜单里面的url要是被人知道的也可以访问,所以控制菜单不是绝对的安全。
菜单是赋值给有这个链接地址权限的用户的,那么是不存在你说的这个问题了。
说白了 我说的菜单就是url,但最终用户知道的只是菜单。
你觉得呢?
补充:在你的上下文里面是存在是否具有这个authority的逻辑的, 如果用户直接访问地址,访问被拒绝。
肯定存在,不存在就没法做到访问控制。
你的安全元数据里面的构造函数逻辑是去数据库把角色对应的资源全部加载到内存,那现在数据量很大,速度很慢怎么办?
另外问你下,loadMenuDefine方法是在系统启动时一次性加载的,进入系统更改了对应关系权限和菜单的关系后,系统不能立即反应过来,你是如何处理的呢?