第9章 保护Web应用----概念梳理

概述:

学习一个简单demo,会有很多疑问需要解决,是时候梳理一下概念。

1、SpringSecurity 模块组成

Spring Security 3.2 分为 11个模块

ACL:支持通过访问控制列表(access Control list, ACL)为域对象提供安全

Aspects(切面): 使用Spring Security注解时,会使用基于AspectJ的切面,而不是标准的SpringAOP

CAS Client :提供与Jasig的中心认证服务(Central Authentication Service, CAS)进行集成的功能

Configuration: 包含通过xml和java配置Spring Security 的功能支持

Core : 提供Spring Security基本库

Cryptography(加密) : 提供了加密和密码编码的功能

LDAP :支持基于LDAP进行认证

OpenID : 支持使用OpenID进行集中式认证

Remoting: 提供了对Spring Remoting 的支持

Tag Library: Spring Security的JSP标签库

Web : 提供了Spring Security基本Filter的Web安全性支持

1.2 过滤Web 请求

安全通过过滤来拦截验证,是否需要配置多个过滤器,其实只要配置一个代理过滤,它会自动找具体实现过滤器

方式一

<filter >

<filter-name>springSecurityFilterChain</filter-name>

<filter-class>

org.springframework.web.filter.DelegatingFilterProxy

</filter-class>

</filer>

方式二:

实现AbstractSecurityWebApplicationInitializer父类

package com.jack.config;

import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;

public class SpringSecurityInitializer extends AbstractSecurityWebApplicationInitializer{

}


1.3 Spring Security 配置 继承WebSecurityConfigurerAdapter

启动安全注解 @EnableWebSecurity

@Configuration
@EnableWebSecurity // 启动web安全控制
public class SecurityConfig extends WebSecurityConfigurerAdapter{
	
	@Autowired
	public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception{
		auth.inMemoryAuthentication().withUser("jack").password("123456").roles("USER");
		auth.inMemoryAuthentication().withUser("admin").password("123456").roles("ADMIN");
		auth.inMemoryAuthentication().withUser("dba").password("123456").roles("DBA");
	}

	@Override
	protected void configure(HttpSecurity http) throws Exception {
		
		http.authorizeRequests()
			.antMatchers("/admin/**").access("hasRole('ROLE_ADMIN')")
			.antMatchers("/dba/**").access("hasRole('ROLE_ADMIN') or hasRole('ROLE_DBA')")
			.and().formLogin();
	}
	
	

}

重写configure入参不同,如下所示

WebSecurity、HttpSecurity、AuthenticationManagerBuilder

配置用户详细信息的方法

accountExpired(boolean) 定义账号是否已经过期

accountLocked(boolean) 定义账号是否已经锁定

and() 用来连接配置

authorities(GrantedAuthority...) 授予某个用户一项或多项权限

authorities(List <? extends GrantedAuthority>) 授予某个用户一项或多项权限

authorities(String ...) 授予某个用户一项或多项权限

credentialsExpired(boolean) 定义凭证是否已经过期

disabled(boolean) 定义账号是否已被禁用

password(String) 定义用户密码

roles(String...) 授予某个用户的一项或多项角色

1.4、基于数据库表进行认证

用到方法是 jdbcAuthentication() 

@Autowired
	DataSource dataSource;
	@Autowired
	public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception{
		
		auth.jdbcAuthentication().dataSource(dataSource);
	}

自定查询语句

@Autowired
	DataSource dataSource;
	@Autowired
	public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception{
		
		auth
		.jdbcAuthentication()
		.dataSource(dataSource)
		.usersByUsernameQuery(
				"select username, password, true "+
				"from Spitter where username=?")
		.authoritiesByUsernameQuery(
				"select username,'ROLE_USER' from Spitter where username=?")
		.passwordEncoder(new StandardPasswordEncoder("532222"));
	}

1.5、基于LDAP 服务器

auth.ldapAuthentication()
		.userSearchBase("ou=people")
		.userSearchFilter("(uid={0})")
		.groupSearchBase("ou=groups")
		.groupSearchFilter("member={0}")
		.passwordCompare()
		.passwordEncoder(new Md5PasswordEncoder())
		.passwordAttribute("passcode");


如果是远程服务。通过contextSource().url("输入地址");

auth.ldapAuthentication()
		.userSearchBase("ou=people")
		.userSearchFilter("(uid={0})")
		.groupSearchBase("ou=groups")
		.groupSearchFilter("member={0}")
		.contextSource()
			.url("ldap://网址")

1.6 非关系型数据库,可以实现 UserDetailsService 接口

重写loadUserByUsername(String username) 方法

package com.jack.data;

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.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

public class SpitterUserService implements UserDetailsService {

	
	private final SpitterRepository spitterRepository;
	public SpitterUserService(SpitterRepository spitterRepository) {
		this.spitterRepository = spitterRepository;
	}
	@Override
	public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
		Spitter spitter = spitterRepository.findByUsername(username);
		if(spitter != null){
			List<GrantedAuthority> authorities = 
					new ArrayList <GrantedAuthority>();
			authorities.add(new SimpleGrantedAuthority("ROLE_SPITTER"));
			
			return new User(spitter.getUsername(),
					spitter.getPassword(),
					authorities);
		}
		throw new UsernameNotFoundException("User '"
				+ "username " + "' not found");
	}

}


总结:

1、不关心数据如何来,只要返回一个User对象就行

配置 auth.userDetailsService(new SpitterUserService(spitterRepository));

1.7 拦截请求

@Override
protected void configure(HttpSecurity http) throws Exception {

http.authorizeRequests()
.antMatchers("/admin/**").access("hasRole('ROLE_ADMIN')")
.antMatchers("/dba/**").access("hasRole('ROLE_ADMIN') or hasRole('ROLE_DBA')")
.and().formLogin();
}

antMatchers() 是Ant风格,也支持regex风格

.regexMatchers()

用来定义如何保护路径的配置方法

access(String) 如果给定的SpEL表达式计算结果为true, 就允许访问

anonymous() 允许匿名用户访问

authenticated() 允许认证过的用户访问

denyAll() 无条件拒绝所有访问

fullyAuthenticated() 如果用户是完整的话(不是通过Remember-me 功能认证的),就能访问

hasAnyAuthority(String...) 如果用户具备给定权限中的某一个的话,就允许访问

hasAnyRole(String...) 如果用户具备给定角色中的某一个的话,就允许访问

hasAuthority(String) 如果用户具备给定权限的话,就允许访问

hasIpAddress(String) 如果请求来自给定IP地址的话,就允许访问

hasRole(String) 如果用户具备给定角色的话,就允许访问

not() 对其他访问方法的结果取反

permitAll () 无条件允许访问

rememberMe() 如果用户是通过Remember-me功能认证的,就允许访问


1.8 强制通道的安全性

HTTPS 加密发送

1.9 防止跨站请求伪造

Cross-site request forgery (CSRF)

通过同步token来解决, 也就是在表单中包含_csrf域

总结:

Spring-Security 可以完成很多验证相关的事情,具体需要慢慢研究

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值