`
huttoncs
  • 浏览: 200866 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

spring security2配置

阅读更多
下面的内容也是在网上查找的资料基础上增加了一下修改,这里也省去了ssh整合的配置,只是针对spring security 2的相关内容

1、首先在web.xml中进行配置
<!-- spring security configuration 这个Filter会拦截所有的URL请求,并且对这些URL请求进行Spring Security的验证 -->
<filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>springSecurityFilterChain</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

和普通的filter配置一样,非常方便

2、spring-security.xml的配置内容如下:
<b:beans xmlns="http://www.springframework.org/schema/security" xmlns:b="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
                        http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.1.xsd">
                       
<b:description>spring security configuration</b:description>
<!-- Spring Security采用就近原则,有多个约束时,从上至下只要找到第一条满足就返回,因此应该将最严格的约束放在最前面,
而将最宽松的约束放在最后面.auto-config属性可以让spring security为我们自动配置几种常用的权限控制机制,
包括form,anonymous, rememberMe等。当然你也可以手工配置。--> 
<http access-denied-page="/access-denied.jsp">
<!-- 我们利用intercept-url来判断用户需要具有何种权限才能访问对应的url资源,可以在pattern中指定一个特定的url资源,
  也可以使用通配符指定一组类似的url资源。例子中定义的两个intercepter-url,第一个用来控制对/security/**的访问,
  第二个使用了通配符/**,说明它将控制对系统中所有url资源的访问。 --> 
<intercept-url pattern="/login.jsp" filters="none" />
<intercept-url pattern="/b.jsp" access="ROLE_ADMIN" />
<intercept-url pattern="/d.jsp" filters="none" />
<form-login login-page="/login.jsp" authentication-failure-url="/login.jsp" always-use-default-target="true" default-target-url="/b.jsp"/>
<logout logout-success-url="/login.jsp"/>
</http>

<!--  验证数据提供器 -->
<authentication-provider user-service-ref='userDetailsService' >
<!-- 将 userDetailsService 的属性username用md5加密
<password-encoder hash="md5">
<salt-source user-property="username"/>
</password-encoder> 
-->
</authentication-provider>

<!-- 鉴权过滤器(URL资源拦截器) -->
<b:bean id="filterSecurityInterceptor" class="org.springframework.security.intercept.web.FilterSecurityInterceptor">
<custom-filter before="FILTER_SECURITY_INTERCEPTOR" /><!-- 指定过滤器应该出现的位置和顺序 -->
<b:property name="authenticationManager" ref="authenticationManager" />
<b:property name="accessDecisionManager" ref="accessDecisionManager" />
<b:property name="objectDefinitionSource" ref="filterInvocationDefinitionSource" />
</b:bean>

<!-- 用户-权限认证管理器 -->
<b:bean id="authenticationManager" class="org.springframework.security.providers.ProviderManager">
<b:property name="providers">
<b:list>
<b:ref local="daoAuthenticationProvider" />
</b:list>
</b:property>
</b:bean>

<!-- 决策管理器(授权器) -->
<b:bean id="accessDecisionManager" class="org.springframework.security.vote.AffirmativeBased">
<b:property name="decisionVoters">
<b:list>
<b:bean class="org.springframework.security.vote.RoleVoter">
<b:property name="rolePrefix" value="" />
</b:bean>
</b:list>
</b:property>
</b:bean>

<!-- 用户认证服务 -->
<b:bean id="daoAuthenticationProvider" class="org.springframework.security.providers.dao.DaoAuthenticationProvider">
<b:property name="userDetailsService" ref="userDetailsService" />
<b:property name="hideUserNotFoundExceptions" value="false" />
</b:bean>

     <!-- 用户信息服务接口 -->
<b:bean id="userDetailsService" class="com.xxx.eb.security.UserDetailsServiceImpl">
<b:property name="dataSource" ref="dataSource" />
<b:property name="usersByUsernameQuery">
<b:value><![CDATA[
select u.id,
       u.username,
       u.password,
       u.enable as enabled
  from
  users u
where u.username = ?
]]></b:value>
</b:property>
<b:property name="authoritiesByUsernameQuery">
<b:value><![CDATA[
select
u.username, r.name as authority
from
users u
join users_roles ur
on u.id = ur.uid
join roles r
on r.id = ur.rid
where
u.username = ?
]]>
</b:value>
</b:property>
</b:bean>

<!-- filter Invocation DefinitionSource  -->
<b:bean id="filterInvocationDefinitionSource" class="com.xxx.eb.security.JdbcFilterInvocationDefinitionSourceFactoryBean">
<b:property name="dataSource" ref="dataSource" />
<b:property name="resourceQuery">
<b:value>
<![CDATA[
select
re.url,r.name
         from
         roles r
            join roles_resources rr
                on r.id=rr.rid
            join resources re
                on re.id=rr.rsid
]]>
</b:value>
</b:property>
</b:bean>
</b:beans>                       

这里我并没有直接采用hibernate的持久化对象,而是使用的JDBC,个人觉得这样更方便,毕竟登录账户数据不会在前台就行操作

3、我把要用用到的实体类及数据库中创建的sql都放在了附件中,都比较简单,这里就不贴出来的了

4、下面是配置文件中要用到的service,各个类的作用在上面的配置文件中都有描述,这里就不再赘述

a、用户登录权限校验类
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import org.springframework.security.GrantedAuthority;
import org.springframework.security.GrantedAuthorityImpl;
import org.springframework.security.userdetails.UserDetailsService;
import org.springframework.security.userdetails.UsernameNotFoundException;

public class UserDetailsServiceImpl extends JdbcDaoSupport implements UserDetailsService {
private String usersByUsernameQuery;
private String authoritiesByUsernameQuery;

/**
* 用户查询服务
*/
@SuppressWarnings("unchecked")
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException {
List<Map<String, Object>> result = super.getJdbcTemplate().queryForList(usersByUsernameQuery, new Object[] { username });
if (result.size() == 1) {
Map<String, Object> row = result.get(0);
row.put(UserDetails.AUTHORITIES, obtainGrantedAuthorities(username));
UserDetails user = new UserDetails();
user.getUserInfo().putAll(row);
return user;
}
throw new UsernameNotFoundException("登陆的账号[" + username + "] 无效!");
}

/**
* 查询用户的角色
*/
@SuppressWarnings("unchecked")
private GrantedAuthority[] obtainGrantedAuthorities(String username) {
List<Map<String, Object>> result = super.getJdbcTemplate().queryForList(this.authoritiesByUsernameQuery, new Object[] { username });
List<GrantedAuthority> grantedAuthoritiesList = new ArrayList<GrantedAuthority>();

for (Map<String, Object> role : result) {
grantedAuthoritiesList.add(new GrantedAuthorityImpl((String) role.get("AUTHORITY")));
}

return (GrantedAuthority[]) grantedAuthoritiesList.toArray(new GrantedAuthority[grantedAuthoritiesList.size()]);
}

/**
* setter
*
* @param usersByUsernameQuery
*            sql
*
*/
public void setUsersByUsernameQuery(String usersByUsernameQuery) {
this.usersByUsernameQuery = usersByUsernameQuery.toUpperCase();
}

/**
* setter
*
* @param authoritiesByUsernameQuery
*            sql
*/
public void setAuthoritiesByUsernameQuery(String authoritiesByUsernameQuery) {
this.authoritiesByUsernameQuery = authoritiesByUsernameQuery.toUpperCase();
}

}


b、下面这个类用于保存登录账户的相关信息
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

import org.springframework.security.GrantedAuthority;

public class UserDetails implements org.springframework.security.userdetails.UserDetails, Serializable {
public static final long serialVersionUID = -3072292482513179894L;
public static final String USER_NAME = "USERNAME";
public static final String PASSWORD = "PASSWORD";
public static final String AUTHORITIES = "AUTHORITIES";
public static final String ENABLED = "ENABLED";

private Map<String, Object> userInfo = new HashMap<String, Object>();

public Map<String, Object> getUserInfo() {
return userInfo;
}

public void setUserInfo(Map<String, Object> userInfo) {
this.userInfo = userInfo;
}

public GrantedAuthority[] getAuthorities() {
return (GrantedAuthority[]) userInfo.get(AUTHORITIES);
}

public String getPassword() {
return (String) userInfo.get(PASSWORD);
}

public String getUsername() {
return (String) userInfo.get(USER_NAME);
}

public boolean isAccountNonExpired() {
return true;
}

public boolean isAccountNonLocked() {
return true;
}

public boolean isCredentialsNonExpired() {
return true;
}

public boolean isEnabled() {
Object enabled = userInfo.get(ENABLED);
if (enabled instanceof Number) {
enabled = String.valueOf(((Number) enabled).intValue());
}

if (enabled instanceof String) {
if (enabled.equals("1") || ((String) enabled).equalsIgnoreCase("true")) {
return true;
}
return false;
}
return false;
}

}


c、用户访问资源权限校验类
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.sql.DataSource;

import org.springframework.beans.factory.FactoryBean;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import org.springframework.jdbc.object.MappingSqlQuery;
import org.springframework.security.ConfigAttributeDefinition;
import org.springframework.security.ConfigAttributeEditor;
import org.springframework.security.intercept.web.DefaultFilterInvocationDefinitionSource;
import org.springframework.security.intercept.web.FilterInvocationDefinitionSource;
import org.springframework.security.intercept.web.RequestKey;
import org.springframework.security.util.AntUrlPathMatcher;
import org.springframework.security.util.UrlMatcher;

/**
* spring security jdbc FactoryBean
* @version 1.0
* /**
* 这个类的目的就是构建一个DefaultFilterInvocationDefinitionSource类,
* DefaultFilterInvocationDefinitionSource是默认提供的FilterInvocationDefinitionSource实现类,省力
* 本类继承FactoryBean给DefaultFilterInvocationDefinitionSource构造的两个参数赋值
*/

public class JdbcFilterInvocationDefinitionSourceFactoryBean extends JdbcDaoSupport implements FactoryBean {

private String resourceQuery;

/**
* (non-Javadoc)
*
* @see org.springframework.beans.factory.FactoryBean#isSingleton()
*/
public boolean isSingleton() {//FactoryBean接口方法
return true;
}

/**
* (non-Javadoc)
*
* @see org.springframework.beans.factory.FactoryBean#getObjectType()
*/
public Class<?> getObjectType() {//FactoryBean接口方法
return FilterInvocationDefinitionSource.class;
}

/**
* (non-Javadoc)
*
* @see org.springframework.beans.factory.FactoryBean#getObject()
*/
public Object getObject() {//工厂方法
//取 构造参数一、二
return new DefaultFilterInvocationDefinitionSource(this.getUrlMatcher(), this.buildRequestMap());
}

/**
* 资源-角色的对应关系
*
* @return
*/
@SuppressWarnings("unchecked")
protected Map<String, String> mappingResource() {
Map<String, String> resourceMap = null;
resourceMap = new LinkedHashMap<String, String>();
ResourceMapping resourceMapping = new ResourceMapping(getDataSource(), resourceQuery);

for (Resource resource : (List<Resource>) resourceMapping.execute()) {
String url = resource.getUrl();
String role = resource.getRole();

if (resourceMap.containsKey(url)) {
String value = resourceMap.get(url);
resourceMap.put(url, value + "," + role);
} else {
resourceMap.put(url, role);
}
}
return resourceMap;
}

/**
* buildRequestMap
* 返回DefaultFilterInvocationDefinitionSource构造参数之二
*/
protected LinkedHashMap<RequestKey, ConfigAttributeDefinition> buildRequestMap() {

LinkedHashMap<RequestKey, ConfigAttributeDefinition> requestMap = null;
//这个Map看起来比较唬人,把握两点:key为URL地址,value为允许访问该URL的角色S,URL与ROLE是多对多的关系
requestMap = new LinkedHashMap<RequestKey, ConfigAttributeDefinition>();

ConfigAttributeEditor editor = new ConfigAttributeEditor();

Map<String, String> resourceMap = this.mappingResource();

for (Map.Entry<String, String> entry : resourceMap.entrySet()) {
//key为URL地址,用RequestKey封装
//value为ConfigAttributeEditor,可以理解为一个数组,该数组中存放ConfigAttribute
//每个ConfigAttribute封装一个角色名称
RequestKey key = new RequestKey(entry.getKey(), null);
editor.setAsText(entry.getValue());
requestMap.put(key, (ConfigAttributeDefinition) editor.getValue());
}

return requestMap;
}

/**
* getter
* 返回DefaultFilterInvocationDefinitionSource构造参数之一
*/
protected UrlMatcher getUrlMatcher() {
return new AntUrlPathMatcher(); //这个比RegexUrlPathMatcher简单,所以用这个,不求甚解
}

/**
* setter
*
* @param resourceQuery
*/
public void setResourceQuery(String resourceQuery) {
this.resourceQuery = resourceQuery;
}

/**
* 资源实体类POJO
*/
private class Resource {
private String url;
private String role;

public Resource(String url, String role) {
this.url = url;
this.role = role;
}

public String getUrl() {
return url;
}

public String getRole() {
return role;
}
}

/**
* 资源-角色查询内部类
*
*/
private class ResourceMapping extends MappingSqlQuery {
protected ResourceMapping(DataSource dataSource, String resourceQuery) {
super(dataSource, resourceQuery);
compile();
}

/**
* (non-Javadoc)
*
* @see org.springframework.jdbc.object.MappingSqlQuery#mapRow(java.sql.ResultSet, int)
*/
protected Object mapRow(ResultSet rs, int rownum) throws SQLException {
String url = rs.getString(1);
String role = rs.getString(2);
Resource resource = new Resource(url, role);

return resource;
}
}
}


5、这个实例用到的jsp页面都很简单,这里我也放到附近中不再贴出来了,只用把这些页面放在项目的更目录下就好。

到此应该就没问题了
0
0
分享到:
评论

相关推荐

    spring security 2 配置说明

    - **配置**:这是Spring Security配置中最核心的部分,通过`&lt;http&gt;`元素可以定义哪些URL需要进行身份验证和授权。`auto-config='true'`属性表示自动配置,简化了配置过程。`&lt;intercept-url&gt;`元素用于指定特定URL的...

    Spring Security 2 配置精讲

    Spring Security 2 配置精讲

    Spring Security2 配置精讲

    Spring Security2 配置 精讲。

    Spring Security2配置精讲

    ### Spring Security2配置精讲 #### 一、Spring Security2简介与配置简化 Spring Security2是Spring框架中的一个重要模块,用于提供安全控制解决方案。相比于前代Acegi安全框架,Spring Security2进行了重大改进,...

    springsecurity使用配置详解

    在提供的压缩包`springsecurity配置demo`中,你将找到示例代码和详细说明,这将帮助你更好地理解和实践上述概念。通过学习和实践这些示例,你将能够为自己的Spring应用程序构建强大的安全防护。

    spring security 项目配置源码

    在这个"Spring Security 项目配置源码"中,我们有机会深入理解这个框架如何在实际项目中配置和使用。下面将详细介绍Spring Security的核心概念、配置过程以及如何在Eclipse环境中运行该项目。 1. **核心概念** - *...

    SpringSecurity 3配置文件

    在本文中,我们将深入探讨Spring Security 3的配置文件,以及如何理解和使用这些配置来增强应用的安全性。 首先,Spring Security的配置通常位于一个或多个XML文件中,这些文件通过`&lt;beans&gt;`标签定义了安全相关的...

    Spring Security in Action

    Spring Security 实践指南 ...* 高度可配置性:Spring Security 的配置项非常灵活,可以根据实际需求进行配置。 Spring Security 是一个功能强大且灵活的安全框架,广泛应用于 Java 应用开发中。

    spring-security3 配置和使用

    Spring Security 3 配置和使用 Spring Security 是一个强大且灵活的安全框架,旨在保护基于 Java 的 Web 应用程序。Spring Security 3 是 Spring Security 框架的第三个主要版本,提供了许多新的功能和改进。下面...

    spring security3配置和使用实例+教程

    教程文档`教你使用_SpringSecurity_3.0_52页.pdf`会详细指导你如何一步步配置和使用Spring Security。它应该包含了配置文件的示例、如何集成到Spring应用中、如何创建自定义认证逻辑以及如何进行授权设置等内容。...

    Spring_Security_2_配置精讲

    2. **中文翻译**:虽然官方文档为英文版,但也有热心网友将其翻译成了中文版,方便国内开发者阅读:[Spring Security 中文版](http://www.family168.com/tutorial/springsecurity/html/springsecurity.html)。...

    Spring Security 资料合集

    - **Java配置**:随着Spring Boot的发展,Spring Security也提供了Java配置方式,更易于理解和维护,通过`@EnableWebSecurity`和`WebSecurityConfigurerAdapter`的子类进行配置。 4. **Remember-Me服务**: - ...

    Spring Security 3.1.3配置实例

    2. **配置Web安全**:在`web.xml`中配置`DelegatingFilterProxy`,这将把HTTP请求委托给Spring Security的过滤器链。 ```xml &lt;filter-name&gt;springSecurityFilterChain &lt;filter-class&gt;org.springframework.web....

    SpringSecurity笔记,编程不良人笔记

    2. **SpringSecurity配置** - XML配置:早期版本的SpringSecurity使用XML配置,但现在已被注解配置取代。 - 注解配置:使用`@EnableWebSecurity`开启Web安全,通过`@Configuration`和`...

    spring security2.x配置

    详细的spring security2.x配置

    SpringSecurity.pdf

    Spring Security的配置灵活,可以通过XML配置文件、Java配置类或者注解来定制安全策略。它还提供了大量的扩展点,允许开发者根据自己的业务需求进行定制和扩展。 Spring Security的学习过程可以分为入门、进阶和...

    spring-security多登录页面配置

    ### Spring Security 多登录页面配置详解 在许多大型企业级应用中,为了更好地实现权限管理和用户体验,往往会采用多个登录页面的方式来进行用户身份验证。这种方式能够有效地将不同类型的用户(如前台用户、后台...

    Springboot整合Spring security+Oauth2+JWT搭建认证服务器,网关,微服务之间权限认证及授权

    4. **整合Spring Security与OAuth2**:在Spring Boot中,我们可以使用`spring-security-oauth2-autoconfigure`库来简化OAuth2的配置。通过设置`@EnableAuthorizationServer`和`@EnableResourceServer`注解,分别启动...

Global site tag (gtag.js) - Google Analytics