Spring Security

一、Spring Security简介

Spring Security是为基于Spring的应用程序提供声明式安全保护的安全性框架。Spring Security提供了完整的安全性解决方案,它能够在Web请求级别和方法调用级别处理身份认证和授权。因为基于Spring框架,所以Spring Security充分利用了依赖注入(dependency injection,DI)和面向切面的技术。

二、Spring Security详情

2.1.实现

Spring Security从两个角度来解决安全性问题:使用Servlet规范中的Filter保护Web请求并限制URL级别的访问;使用Spring AOP保护方法调用——借助于对象代理和使用通知,能够确保只有具备适当权限的用户才能访问安全保护的方法。

对于Spring Security来说主要提供的两个安全服务是指:认证(Authentication)和 授权(Authorization);认证是用来确定当前用户,授权是判断一个用户是否有访问某个安全对象的权限。

2.2.Spring Security模块

下面常用的模块包括:配置(config)、核心(core)和Web是必须要的;标签库也是常用的模块。

Spring Security标签库支持的标签包括:

 

2.3.Spring Security用户认证

Spring Security中提供了多种的用户认证策略,常用的认证策略包括(认证将在后面详细说明过程):

         1.基于内存的用户存储(下面第一个Demo就是基于内存的用户存储)

         2.基于数据库表进行认证(将在后面展示Demo)

         3.基于LDAP进行用户认证(将在后面展示Demo)

三、示例

下面示例展示了通过JavaConfig的方式集成spring-security安全框架

1,实现AbstractSecurityWebApplicationInitializer,只用写好一个实现类就可以了,Spring系统会发现他,并用他在web容器中注册DelegetingFilterProxy。DelegetingFilterProxy会拦截发往应用中的请求。并将请求委托给一个ID为springSecurityFilterChain的bean,该bean可以连接一个或任意多个Filter,Spring security就是依赖着一系列servlet filter来提供不同的安全特性。这些细节我们不用管,当启用web安全性时,会自动创建这些filter。

package com.cc.test.security;
 
import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;
 
public class SecurityWebInitializer extends AbstractSecurityWebApplicationInitializer {
}

2,创建SecurityConfig

package com.cc.test.config;
 
import javax.sql.DataSource;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.password.StandardPasswordEncoder;
 
import com.halfworlders.idat.security.IdatUserDetailsService;
import com.halfworlders.idat.service.Userservice;
 
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
//	@Autowired
//	private DataSource dataSource;
 
	@Autowired
	private Userservice userservice;
	
	@Override
	protected void configure(AuthenticationManagerBuilder auth) throws Exception {
		/*
		 * 可以通过内存设置的方式,来做用户登录验证,此种方式比较适合开发和测试阶段使用
		 */
		/*auth
		.inMemoryAuthentication()
		.withUser("admin")
		.password("admin")
		.roles("ADMIN");*/
 
		/*
		 * 可以通过数据源设置的方式,直接基于数据库的验证,还可以设置密码加密,
		 * 但此种方式要求数据库的用户表结构必须符合spring-security的要求
		 * 一下配上sql
		 */
		/*auth
		.jdbcAuthentication()
		.dataSource(dataSource)
		.passwordEncoder(new StandardPasswordEncoder("idatpwd"));*/
 
		/*
		 * 最好的是基于UserDetailService的接口方式,这样spring-security并不知道系统通过什么样的方式来实现用户数据验证
		 * 开发人员可以在接口内以任意方式实现,增加了系统的灵活性
		 */
		auth.userDetailsService(new IdatUserDetailsService(userservice));
	}
}

3,在TilesWebConfig中导入配置

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.halfworlders.idat.controller")
@Import(SecurityConfig.class)
public class TilesWebConfig extends WebMvcConfigurerAdapter {
。。。。。
}

只需这三步,就能轻松的启用了Spring security安全框架

另外再需要实现UserDetailsService

package com.cc.test.security;
 
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
 
import com.halfworlders.idat.service.Userservice;
 
public class IdatUserDetailsService implements UserDetailsService{
 
	private final Userservice userservice;
	
	public IdatUserDetailsService(Userservice userservice) {
		this.userservice = userservice;
	}
	@Override
	public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {
		User user = userservice.findUserByName(userName);
		if (null != user) {
			return user;
		}
		throw new UsernameNotFoundException("User name" + userName + "not find");
	}
 
}


UserService

package com.cc.test.service;
 
import org.springframework.security.core.userdetails.User;
 
public interface Userservice {
	User findUserByName(String userName);
}
package com.cc.test.service.impl;
 
import java.util.ArrayList;
import java.util.List;
 
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.stereotype.Service;
 
import com.halfworlders.idat.service.Userservice;
 
@Service
public class UserServiceImpl implements Userservice {
 
	@Override
	public User findUserByName(String userName) {
		List<GrantedAuthority> grantedAuthorities = new ArrayList<GrantedAuthority>();
		grantedAuthorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
		return new User(userName, "admin", grantedAuthorities);
	}
}

mysql-sql

SET FOREIGN_KEY_CHECKS=0;
 
-- ----------------------------
-- Table structure for authorities
-- ----------------------------
DROP TABLE IF EXISTS `authorities`;
CREATE TABLE `authorities` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(20) DEFAULT NULL,
  `authority` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
 
-- ----------------------------
-- Table structure for groups
-- ----------------------------
DROP TABLE IF EXISTS `groups`;
CREATE TABLE `groups` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `groupName` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
 
-- ----------------------------
-- Table structure for group_authorities
-- ----------------------------
DROP TABLE IF EXISTS `group_authorities`;
CREATE TABLE `group_authorities` (
  `group_Id` int(11) NOT NULL AUTO_INCREMENT,
  `authority` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`group_Id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
 
-- ----------------------------
-- Table structure for group_members
-- ----------------------------
DROP TABLE IF EXISTS `group_members`;
CREATE TABLE `group_members` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `userName` varchar(20) DEFAULT NULL,
  `group_Id` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
 
-- ----------------------------
-- Table structure for users
-- ----------------------------
DROP TABLE IF EXISTS `users`;
CREATE TABLE `users` (
  `id` int(8) NOT NULL AUTO_INCREMENT,
  `userName` varchar(20) DEFAULT NULL,
  `password` varchar(50) DEFAULT NULL,
  `enabled` tinyint(4) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

四、参考

《Spring In Action(第四版)》

https://blog.youkuaiyun.com/u013468915/article/details/81347063

http://www.cnblogs.com/wutianqi/p/9185266.html

http://www.cnblogs.com/wutianqi/p/9186645.html

https://www.cnblogs.com/jaylon/p/4905769.html

https://www.cnblogs.com/guoziyi/p/6001085.html

https://www.cnblogs.com/xz816111/p/8528896.html

https://blog.youkuaiyun.com/elim168/article/details/72869685

https://blog.youkuaiyun.com/kaikai8552/article/details/3930747

https://blog.youkuaiyun.com/lbqssss/article/details/78971037

https://blog.youkuaiyun.com/lifeifei2010/article/details/78787558

https://blog.youkuaiyun.com/marvel__dead/article/details/77094848

Spring SecuritySpring 生态系统中的核心组件,也是一个功能强大且高度可定制的身份验证和访问控制框架,是保护基于 Spring 的应用程序的事实上的标准,致力于为 Java 应用程序提供身份验证和授权,通过提供认证(Authentication)与授权(Authorization)和针对常见攻击等一系列安全功能,为开发者构建安全稳定的应用提供强有力的支持,且可轻松扩展以满足自定义需求 [^1][^2]。 ### 使用指南 Spring Security 会对 `/login` 的 POST 请求做拦截,校验表单中用户名和密码,这一功能由 `UsernamePasswordAuthenticationFilter` 实现 [^3]。在实际使用时,通常要创建一个配置类来定制 Spring Security 的行为。以下是一个简单示例: ```java import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.web.SecurityFilterChain; @Configuration public class SecurityConfig { @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http .authorizeRequests() .anyRequest().authenticated() .and() .formLogin() .and() .httpBasic(); return http.build(); } } ``` 上述代码配置了所有请求都需要认证,支持表单登录和 HTTP 基本认证。 ### 配置方法 Spring Security 的配置主要通过 Java 配置类和注解来完成。 - **Java 配置类**:继承 `WebSecurityConfigurerAdapter`(Spring Boot 2.7.x 之前)或者使用 `SecurityFilterChain` Bean(Spring Boot 2.7.x 及之后)来配置安全策略。 ```java import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.web.SecurityFilterChain; @Configuration public class CustomSecurityConfig { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/public/**").permitAll() .anyRequest().authenticated() .and() .formLogin() .loginPage("/login") .permitAll() .and() .logout() .permitAll(); return http.build(); } } ``` 以上代码配置了 `/public` 路径下的请求无需认证,其他请求需要认证,自定义了登录页面,并允许注销操作。 - **注解**:使用 `@EnableWebSecurity` 启用 Spring Security 的 Web 安全支持。 ### 最佳实践 - **使用 HTTPS**:在生产环境中,使用 HTTPS 来加密数据传输,防止数据被窃取和篡改。 - **密码加密**:在存储用户密码时,使用安全的加密算法,如 BCrypt。 ```java import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; public class PasswordEncoderExample { public static void main(String[] args) { PasswordEncoder encoder = new BCryptPasswordEncoder(); String encodedPassword = encoder.encode("password123"); System.out.println(encodedPassword); } } ``` - **细粒度的访问控制**:根据用户角色和权限,对不同的资源和 URL 进行细粒度的访问控制。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值