【Spring学习】spring集成springsecurity

springsecurity搭建

我们在springmvc项目的基础上,集成springsecurity

引入必要的jar

	<dependency>
		<groupId>org.springframework.security</groupId>
		<artifactId>spring-security-core</artifactId>
		<version>4.2.4.RELEASE</version>
	</dependency>
	<dependency>
		<groupId>org.springframework.security</groupId>
		<artifactId>spring-security-config</artifactId>
		<version>4.2.4.RELEASE</version>
	</dependency>
	<dependency>
		<groupId>org.springframework.security</groupId>
		<artifactId>spring-security-web</artifactId>
		<version>4.2.4.RELEASE</version>
	</dependency>

继承AbstractSecurityWebApplicationInitializer

该类继承了WebApplicationInitializer,所以会被spring容器发现,并且spring会用它在web容器中注册DelegatingFilterProxy,而这个类会拦截发往应用中的请求,并将请求委托给ID为springSecurityFilterChain 的bean。

springSecurityFilterChain本身是一个特殊的Filter,它可以链接任意一个或多个其他的filter.Spring security依赖一系列Servlet Filter来提供不同的安全特性。

public class SecurityWebInitializer extends AbstractSecurityWebApplicationInitializer {

}

让Web安全性运行起来

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

}

@EnableWebSecurity注解会启用Web安全功能。但它本身并没有什么作用,它需要配置在一个实现了WebSecurityConfigurerAdapter类的配置类尚

让spring扫描到该配置类

public class WebApplication extends AbstractAnnotationConfigDispatcherServletInitializer {

	@Override
	protected Class<?>[] getRootConfigClasses() {
		return new Class[] { RootConfig.class, SecurityConfig.class };
	}

	@Override
	protected Class<?>[] getServletConfigClasses() {
		return new Class[] { WebConfig.class };
	}

	@Override
	protected String[] getServletMappings() {
		return new String[] { "/" };
	}

}

不然会报找不到springSecurityFilterChain 这个bean

到这里我们还无法访问程序,因为 1没有配用户的相关信息 2 没有配访问路径权限控制

spring支持内存、关系数据库和LDAP

基于内存的用户存储访问

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

	@Override
	protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
	     auth.inMemoryAuthentication()// 内存存储用户
            .withUser("zhangsan")// 创建一个用户名
            .password("123")//密码
            .roles("guest")//赋予的角色
            .and()// 连接符
            .withUser("admin")
			.password("123")
            .roles("admin");
	}

	@Override
	protected void configure(final HttpSecurity http) throws Exception {
		http.authorizeRequests() // 开启登陆配置
				.antMatchers(HttpMethod.GET,"/swagger").permitAll()// 不用登陆的路径
                .anyRequest().authenticated()// 其他路径都要认证授权
            	.and().formLogin()// 支持form表单登陆
				.and().httpBasic();// 支持basic登陆
	}

}

只需要重写configure(AuthenticationManagerBuilder auth)方法,就可以配置多种用户存储方式。

重写configure(final HttpSecurity http)就可以配置路径访问控制。

新建一个控制器

@Controller
public class LoginController {

	@RequestMapping(value = "/", method = RequestMethod.GET)
	public String home() {
		System.out.println("home");
		return "home";
	}
	@RequestMapping(value = "user", method = RequestMethod.GET)
	public String user() {
		System.out.println("user");
		return "user";
	}
}

补充:如果我们直接访问 /user,那么会被拦截进行登陆验证,然后输入用户名密码后,并没有重定向到/user,而是重定向到"/"路径,这点要注意。当然我们也可以配置登陆成功的路径。

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

		http.authorizeRequests() // 开启登陆配置
		        .antMatchers(HttpMethod.GET, "/swagger").permitAll()
				.anyRequest().permitAll()
				.and().formLogin()
				.defaultSuccessUrl("/success")// 登陆成功后默认的跳转的URL
				.and().httpBasic();
	}

另外,/login这个路径是springsecurity的默认登陆路径,如果我们直接访问该路径,则会跳转到登陆页面。

使用关系型数据库
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

	@Autowired
	UserDetailsService uds;

	@Override
	protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
		// 配置数据库访问方式
		auth.userDetailsService(uds);
	}

	@Override
	protected void configure(final HttpSecurity http) throws Exception {
		http.authorizeRequests() // 开启登陆配置
				.antMatchers(HttpMethod.GET, "/swagger").permitAll().anyRequest().authenticated().and().formLogin()
				.and().httpBasic();
	}

}
@Component
public class UserService implements UserDetailsService {

	public UserDetails loadUserByUsername(final String username) throws UsernameNotFoundException {

		if (!"zhangsan".equals(username)) {
			// 如果数据库不存在,则抛UsernameNotFoundException,springsecurity会捕获该异常
			throw new UsernameNotFoundException("not zhangsan");
		}
		// 获取用户权限
		List<GrantedAuthority> authoritys = new ArrayList<GrantedAuthority>();
		authoritys.add(new SimpleGrantedAuthority("admin"));
		return new User("zhangsan", "123", authoritys);
	}

}
退出

退出功能是通过Servlet容器中的filter实现的。这个Filter会拦截针对“/logout"的请求,因此只需要调用”/logout“即可。

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

		http.authorizeRequests() // 开启登陆配置
				.antMatchers(HttpMethod.GET, "/swagger").permitAll()
				.anyRequest().authenticated()
				.and().formLogin()
				.and().httpBasic()
				.and().logout()// 配置退出
				.logoutSuccessUrl("/");//退出成功重定向的url
	}

但是上面配置后,调用”/logout“没生效,而且报404

原来:默认情况下”/logout”必须使用POST提交才可以起作用
原因:CSRS功能默认开启了

解决办法:要么使用post请求,要么关闭CSRS

	@Override
	protected void configure(final HttpSecurity http) throws Exception {
		http.authorizeRequests() // 开启登陆配置
				.antMatchers(HttpMethod.GET, "/swagger").permitAll()
				.anyRequest().authenticated().and().formLogin()											.and().httpBasic()
				.and().logout().logoutSuccessUrl("/")
				.and().csrf().disable();// 关闭CSRS
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值