欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

spring-security3.2.5实现中国式安全管理

程序员文章站 2022-07-14 23:05:45
...
    最近公司要做开发平台,对安全要求比较高;SPRING SECURTIY框架刚好对所有安全问题都有涉及,框架的作者最近还做了spring-session项目实现分布式会话管理,还有他的另一个开源项目spring-security-oauth2。
   
    关于spring-security的配置方法,网上有非常多的介绍,大都是基于XML配置,配置项目非常多,阅读和扩展都不方便。其实spring-security也有基于java的配置方式,今天就讲讲如何通过java配置方式,扩展spring-security实现权限配置全部从表中读取。

    直接上代码:

application.properties配置文件
privilesByUsernameQuery= select  authority from user_authorities  where username = ?
allUrlAuthoritiesQuery=SELECT authority_id , url   FROM Url_Authorities


javaconfig

/**
 *
 */
package com.sivalabs.springapp.config;

import java.util.List;

import javax.annotation.Resource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
//import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.util.StringUtils;

import com.sivalabs.springapp.entities.UrlAuthority;
import com.sivalabs.springapp.repositories.UserRepository;

/**
 * @author tony
 *
 */
@Configuration
@EnableWebSecurity(debug = true)
// @EnableGlobalMethodSecurity(prePostEnabled = true)
// @ImportResource("classpath:applicationContext-security.xml")
public class SecurityConfig extends WebSecurityConfigurerAdapter {

	@Autowired
	JdbcTemplate jdbcTemplate ;

	@Autowired
	private Environment env;

	@Bean
	CustomUserDetailsService customUserDetailsService() {
		//==================application.properties文件中配置2个SQL=============
		//privilesByUsernameQuery= select  authority from user_authorities  where username = ?
		//allUrlAuthoritiesQuery=SELECT authority_id , url   FROM Url_Authorities
		String privilesByUsernameQuery = env.getProperty("privilesByUsernameQuery");
		String allUrlAuthoritiesQuery = env.getProperty("allUrlAuthoritiesQuery");

		CustomUserDetailsService customUserDetailsService = new CustomUserDetailsService();
		customUserDetailsService.setJdbcTemplate(jdbcTemplate);
		customUserDetailsService.setEnableGroups(false);
		//根据登录ID,查登录用户的所有权限
		if(StringUtils.hasLength(privilesByUsernameQuery))
			customUserDetailsService.setAuthoritiesByUsernameQuery(privilesByUsernameQuery);
		//所有URL与权限的对应关系
		if(StringUtils.hasLength(privilesByUsernameQuery))
			customUserDetailsService.setAllUrlAuthoritiesQuery(allUrlAuthoritiesQuery);
		return customUserDetailsService;
	}

	@Resource(name = "userRepository")
	private UserRepository userRepository;

	@Override
	protected void configure(AuthenticationManagerBuilder registry)
			throws Exception {
		/*
		 * registry .inMemoryAuthentication() .withUser("siva") // #1
		 * .password("siva") .roles("USER") .and() .withUser("admin") // #2
		 * .password("admin") .roles("ADMIN","USER");
		 */

		// registry.jdbcAuthentication().dataSource(dataSource);
		registry.userDetailsService(customUserDetailsService());
	}

	@Override
	public void configure(WebSecurity web) throws Exception {
		web.ignoring().antMatchers("/resources/**"); // #3web
	}


	// AntPathRequestMatcher --> AntPathRequestMatcher --->AntPathMatcher
	@Override
	protected void configure(HttpSecurity http) throws Exception {
		//1.登录注册等URL不要身份验证
		http.csrf().disable().authorizeRequests()
				.antMatchers("/login", "/login/form**", "/register", "/logout")
				.permitAll() // #4
				.antMatchers("/admin", "/admin/**").hasRole("ADMIN"); // #6

		//2. 从数据库中读取所有需要权限控制的URL资源,注意当新增URL控制时,需要重启服务
		List<UrlAuthority> urlAuthorities = customUserDetailsService().loadUrlAuthorities();
		for (UrlAuthority urlAuthority : urlAuthorities) {
			http.authorizeRequests().antMatchers(urlAuthority.getUrl()).hasAuthority(String.valueOf(urlAuthority.getId()));
		}

		//3. 除1,2两个步骤验证之外的URL资源,只要身份认证即可访问
		http.authorizeRequests().anyRequest().authenticated() // 7
				.and().formLogin() // #8
				.loginPage("/login/form") // #9
				.loginProcessingUrl("/login").defaultSuccessUrl("/welcome") // #defaultSuccessUrl
				.failureUrl("/login/form?error").permitAll(); // #5

	}

}




1.读取数据库中的URL资源对应的权限列表
2.读取登录用户拥有的权限列表
/**
 *
 */
package com.sivalabs.springapp.config;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

import org.springframework.jdbc.core.RowMapper;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl;

import com.sivalabs.springapp.entities.UrlAuthority;


/**
 * @author tony
 *
 */
public class CustomUserDetailsService extends JdbcDaoImpl{

    private String allUrlAuthoritiesQuery ;


	/**
	  * 从数据库中读取所有需要权限控制的URL资源,注意当新增URL控制时,需要重启服务
     */
    public List<UrlAuthority> loadUrlAuthorities( ) {
        return getJdbcTemplate().query(allUrlAuthoritiesQuery,  new RowMapper<UrlAuthority>() {
            public UrlAuthority mapRow(ResultSet rs, int rowNum) throws SQLException {
            	return new UrlAuthority (rs.getInt(1),rs.getString(2));
            }
        });
    }


    /**
     *  从数据库中读取用户权限
     * Loads authorities by executing the SQL from <tt>authoritiesByUsernameQuery</tt>.
     * @return a list of GrantedAuthority objects for the user
     */
    protected List<GrantedAuthority> loadUserAuthorities(String username) {
        return getJdbcTemplate().query(super.getAuthoritiesByUsernameQuery(), new String[] {username}, new RowMapper<GrantedAuthority>() {
            public GrantedAuthority mapRow(ResultSet rs, int rowNum) throws SQLException {
                String roleName =  rs.getString(1);
                return new SimpleGrantedAuthority(roleName);
            }
        });
    }

	public void setAllUrlAuthoritiesQuery(String allUrlAuthoritiesQuery) {
		this.allUrlAuthoritiesQuery = allUrlAuthoritiesQuery;
	}

}



测试数据及案例见
http://note.youdao.com/share/?id=c20e348d9a08504cd3ac1c7c58d1026e&type=note

spring-security-oauth2
http://www.mvnrepository.com/artifact/org.springframework.security.oauth/spring-security-oauth2

Maven Repository: org.springframework.session » spring-session
http://www.mvnrepository.com/artifact/org.springframework.session/spring-session