最近公司要做开发平台,对安全要求比较高;SPRING SECURTIY框架刚好对所有安全问题都有涉及,框架的作者最近还做了spring-session项目实现分布式会话管理,还有他的另一个开源项目spring-security-oauth2。 关于spring-security的配置方法,网上有非常多的介绍,大都是基于XML配置,配置项目非常多,阅读和扩展都不方便。其实spring-security也有基于java的配置方式,今天就讲讲如何通过java配置方式,扩展spring-security实现权限配置全部从表中读取。
直接上代码:
application.properties配置文件
Java代码
- privilesByUsernameQuery= select authority from user_authorities where username = ?
- allUrlAuthoritiesQuery=SELECT authority_id , url FROM Url_Authorities
javaconfig
Java代码
- /**
- *
- */
- 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.读取登录用户拥有的权限列表
Java代码
- /**
- *
- */
- 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
- springmvc-datajpa-security-demo.zip (964.9 KB)
http://json20080301.iteye.com/blog/2190711