SpringSecurity--基本使用--1

1、简介

应用程序的安全性通常体现在两个方面:认证和授权。
认证是确认某主体在某系统中是否合法、可用的过程。这里的主体既可以是登录系统的用户,也 可以是接入的设备或者其他系统。
授权是指当主体通过认证之后,是否允许其执行某项操作的过程。 这些概念并非Spring Security独有,而是应用安全的基本关注点。Spring Security可以帮助我们更便 捷地完成认证和授权。

2、基本使用

1、依赖引入

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.my.test.security</groupId>
  <artifactId>SpringSecurityTest</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  
  <parent>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-parent</artifactId>
	<version>2.1.4.RELEASE</version>
  </parent>
  
  <dependencies>
  	<!-- SpringBoot依赖 -->
  	<dependency>
	    <groupId>org.springframework.boot</groupId>
	    <artifactId>spring-boot-starter-web</artifactId>
	</dependency>
  
	<!-- SpringSecurity -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    
    <!-- jdbc -->
    <dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-jdbc</artifactId>
	</dependency>
	
	<!-- mysql -->	
	<dependency>
		<groupId>mysql</groupId>
		<artifactId>mysql-connector-java</artifactId>
	</dependency>
    <!-- lombok依赖 -->
	<dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>
    <!--  -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
    </dependency>
  </dependencies>
</project>

2、controller及启动类

@SpringBootApplication
@RestController
public class SecurityApp {
	
	@GetMapping("/")
	public String hello() {
		return "Welcome to hello page";
	}

	public static void main(String[] args) {
		SpringApplication.run(SecurityApp.class, args);
	}
}

3、配置文件配置

server:
  port: 8888
spring:
  security:
    user:
      name: root
      password: Admin123
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/my_test?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8
    username: root
    password: 666666

4、测试
访问:localhost:8888时,会进行验证,输入配置好的用户名密码便可进入访问的controller

3、WebSecurityConfigurerAdapter实现路由及身份权限验证

1、依赖
同2中依赖

2、配置类-继承WebSecurityConfigurerAdapter并进行设置

@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

	@Override
	protected void configure(HttpSecurity http) throws Exception {
		 /**
		   * session管理策略
		   * 	ALWAYS---总是创建HttpSession
			 	IF_REQUIRED---Spring Security只会在需要时创建一个HttpSession
			 	NEVER---Spring Security不会创建HttpSession,但如果它已经存在,将可以使用HttpSession
			 	STATELESS---Spring Security永远不会创建HttpSession,它不会使用HttpSession来获取SecurityContext
		   */
		http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.NEVER);
		http.authorizeRequests()
		/**
		 * 设置用户及角色认证,控制controller的访问权限
		 */
		.antMatchers("/user/**").hasRole("USER")
		.antMatchers("/manager").hasRole("MANAGER")
		//登出跳转
		.antMatchers("/logoutSuccess").permitAll()
		.antMatchers("/").permitAll()
		.and()
		.formLogin() //基于表单登录
		.permitAll() //允许访问登录
		
		/* 指定登录页 */
		//.loginPage("/login") 
		
		/* 指定登录时访问的URL */
		//.loginProcessingUrl("/security/login") 
		
		.and()
		.logout()
		/*退出时访问的url*/
		.logoutUrl("/logout")
		/**
		 * 注意logoutSuccessUrl不要与logoutSuccessHandler一起使用,否则logoutSuccessHandler将失效。
		 */
		
		/*退出成功后要做的操作(如记录日志),和logoutSuccessUrl互斥*/
		//.logoutSuccessHandler(new CoreqiLogoutSuccessHandler())
		
		/*退出成功后跳转的页面--需配置权限,否则会转向登录页*/
		.logoutSuccessUrl("/logoutSuccess")
		
		/*退出时要删除的Cookies的名字*/
		//.deleteCookies("JSESSIONID")    
		.and()
		//csrf是Spring Security提供的跨站请求伪造防护功能
		.csrf().disable();
		super.configure(http);
	}

	@Override
	protected void configure(AuthenticationManagerBuilder auth) throws Exception {
		
		/**
		 * 普通用户权限设置
		 */
		auth.inMemoryAuthentication()
		.passwordEncoder(new BCryptPasswordEncoder())
		.withUser("user") 
		/*密码需进行编码存储,否则匹配时,会自动进行解码操作*/
		.password(new BCryptPasswordEncoder().encode("user123")).roles("USER");
		
		/**
		 * 管理员权限设置
		 */
		auth.inMemoryAuthentication()
		.passwordEncoder(new BCryptPasswordEncoder()).withUser("manager") 
		.password(new BCryptPasswordEncoder().encode("manager123")).roles("MANAGER");
	}
}

3、controller层代码

@SpringBootApplication
@RestController
public class SecurityApp {
	
	@GetMapping("/")
	public String hello() {
		return "Welcome to hello page";
	}
	
	@GetMapping("/user")
	public String userPage() {
		return "user page";
	}
	
	@GetMapping("/manager")
	public String managerPage() {
		return "manager page";
	}
	
	@GetMapping("/logoutSuccess")
	public String logoutPage() {
		return "logout success!";
	}
	
	public static void main(String[] args) {
		SpringApplication.run(SecurityApp.class, args);
	}
}

4、使用SpringSecurity结合SpringDataJpa实现RBAC模式权限管理

1、使用登录成功/失败后置处理–Handler
成功Handler

@Component
public class LoginSuccessHandler implements AuthenticationSuccessHandler{
	@Override
	public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
			Authentication authentication) throws IOException, ServletException {
		response.setContentType("application/json; charset=utf-8");
		response.sendRedirect("/user");
	}
}

失败Handler

@Component
public class LoginFailureHandler implements AuthenticationFailureHandler {
	@Override
	public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
			AuthenticationException exception) throws IOException, ServletException {
		System.out.println("登录失败!");
		response.sendRedirect("/logoutFailure");
	}
}

2、实体类继承UserDetails并实现authorities的list以及dao接口
实体类

@Entity
@Table(name = "security_user")
@Data
public class SecurityUser implements UserDetails{
	
	private static final long serialVersionUID = 1L;

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	@Column(name = "id")
	private Integer id;
	
	@Column(name = "username")
	private String username;
	
	@Column(name = "password")
	private String password;
	
	/*GrantedAuthority接口的默认实现SimpleGrantedAuthority*/
	@ElementCollection(targetClass = GrantedAuthority.class) 
	private List<GrantedAuthority> authorities;

	@Override
	public Collection<? extends GrantedAuthority> getAuthorities() {
		return this.authorities;
	}

	@Override
	public boolean isAccountNonExpired() {
		// TODO Auto-generated method stub
		return true;
	}

	@Override
	public boolean isAccountNonLocked() {
		// TODO Auto-generated method stub
		return true;
	}

	@Override
	public boolean isCredentialsNonExpired() {
		// TODO Auto-generated method stub
		return true;
	}

	@Override
	public boolean isEnabled() {
		// TODO Auto-generated method stub
		return true;
	}
}

dao接口

public interface UserDao extends JpaRepository<SecurityUser, Integer>, JpaSpecificationExecutor<SecurityUser> {
	@Query(value = "select * from security_user as u where u.username = ?1",nativeQuery = true)
	SecurityUser getUserByUsername(String username);
}

3、实现UserDetailsService并配置user

@Service
public class UserDetailServiceImp implements UserDetailsService {
	
	@Autowired
	private UserDao userDao;
	
	@Override
	public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {	
		
		PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
		SecurityUser user = userDao.getUserByUsername(username);
		user.setUsername(username);
		user.setPassword(encoder.encode(user.getPassword()));
		//user.setPassword(user.getPassword());
		
		List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
		GrantedAuthority authority = new SimpleGrantedAuthority("ROLE_USER");
		authorities.add(authority);
		user.setAuthorities(authorities);
		
		return user;
	}
}

4、WebSecurityConfig注入UserDetailsService实现类及其他配置

@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

	@Autowired
	private LoginSuccessHandler successHandler;

	@Autowired
	private LoginFailureHandler failureHandler;

	@Autowired
	private UserDetailsService userDetailServiceImp;

	@Override
	protected void configure(HttpSecurity http) throws Exception {
		/**
		 * session管理策略 ALWAYS---总是创建HttpSession IF_REQUIRED---Spring
		 * Security只会在需要时创建一个HttpSession NEVER---Spring
		 * Security不会创建HttpSession,但如果它已经存在,将可以使用HttpSession STATELESS---Spring
		 * Security永远不会创建HttpSession,它不会使用HttpSession来获取SecurityContext
		 */
		http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.NEVER);
		http.authorizeRequests()
				/**
				 * 设置用户及角色认证,控制controller的访问权限
				 */
				.antMatchers("/user/**").hasRole("USER")
				.antMatchers("/manager").hasRole("MANAGER")
				// 登出跳转
				.antMatchers("/logoutSuccess").permitAll()
				.antMatchers("/").permitAll().and().formLogin() // 基于表单登录
				.permitAll() // 允许访问登录
				.successHandler(successHandler).failureHandler(failureHandler)
				/* 指定登录页 */
				// .loginPage("/login")

				/* 指定登录时访问的URL */
				// .loginProcessingUrl("/security/login")

				.and().logout()
				/* 退出时访问的url */
				.logoutUrl("/logout")
				/**
				 * 注意logoutSuccessUrl不要与logoutSuccessHandler一起使用,否则logoutSuccessHandler将失效。
				 */

				/* 退出成功后要做的操作(如记录日志),和logoutSuccessUrl互斥 */
				// .logoutSuccessHandler(new CoreqiLogoutSuccessHandler())

				/* 退出成功后跳转的页面--需配置权限,否则会转向登录页 */
				.logoutSuccessUrl("/logoutSuccess")

				/* 退出时要删除的Cookies的名字 */
				// .deleteCookies("JSESSIONID")

				.and()
				// csrf是Spring Security提供的跨站请求伪造防护功能
				.csrf().disable();
		super.configure(http);
	}

	@Override
	protected void configure(AuthenticationManagerBuilder auth) throws Exception {
		auth.userDetailsService(userDetailServiceImp);
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值