spring boot下配置spring security笔记(请面试官进来看看)

springboot所有的配置是无xml的,用webinitlizer继承

AbstractAnnotationConfigDispatcherServletInitializer

配置拦截器等

在实现类中getServletFilters
DelegatingFilterProxy securityFilterChain = new DelegatingFilterProxy("springSecurityFilterChain");
return new Filter[] {characterEncodingFilter, securityFilterChain};
就可以开启拦截了


在实现类中

@Override
protected Class<?>[] getRootConfigClasses() {
    return new Class<?>[]{RootConfig.class,SecurityConfig.class};
}
就可以注册一个拦截相关的实现类实现auto认证与http认证啦!!!



===================================ruo======================================

以下为我遇到的错误信息

1.csrfException,场景,因为我是通过webservice调用的 属于无状态请求,所以需要在securityConfig里设置.and().csrf().disable()禁用即可

2.AccessDeniedException: Access is denied

这个是指我没有访问这个url地址的权限

3.

loadUserByUsername(String username)
soa架构下万年获取不到username的问题,这个教科书和百度上并没有具体的告诉我

.formLogin()
.loginPage("/login")
.loginProcessingUrl("/loginProcessing")

 

4.InternalAuthenticationService

UserAccountEntity类实现spring的 org.springframework.security.core.userdetails.UserDetails实现equals与hashCode方法

@Override
public boolean equals(Object rhs) {
    if (!(rhs instanceof User) || (rhs == null)) {
        return false;
    }
    User user = (User) rhs;
    return (this.getPassword().equals(user.getPassword()) && this.getUsername().equals(user.getUsername())
            && (this.isAccountNonExpired() == user.isAccountNonExpired())
            && (this.isAccountNonLocked() == user.isAccountNonLocked())
            && (this.isCredentialsNonExpired() == user.isCredentialsNonExpired())
            && (this.isEnabled() == user.isEnabled()));
}

@Override
public int hashCode() {
    int code = 9792;
    for (GrantedAuthority authority : getAuthorities()) {
        code = code * (authority.hashCode() % 7);
    }

    if (this.getPassword() != null) {
        code = code * (this.getPassword().hashCode() % 7);
    }

    if (this.getUsername() != null) {
        code = code * (this.getUsername().hashCode() % 7);
    }

    if (this.isAccountNonExpired()) {
        code = code * -2;
    }

    if (this.isAccountNonLocked()) {
        code = code * -3;
    }

    if (this.isCredentialsNonExpired()) {
        code = code * -5;
    }

    if (this.isEnabled()) {
        code = code * -7;
    }

    return code;
}

5.客户端请求这个,不要去请求login这个地址

org.springframework.security.authentication.BadCredentialsException: Bad credentials

DaoAuthenticationProvider
if(!this.passwordEncoder.isPasswordValid(userDetails.getPassword(), presentedPassword, salt)) {
这是由于我密码配置错误导致的,让我们加到config auth这个方法

auth.userDetailsService(spitterUserService).passwordEncoder(new BCryptPasswordEncoder());
改成
auth.userDetailsService(spitterUserService).passwordEncoder(new Md5PasswordEncoder());

即可

6.问:如果不让springboot重定向 并且返回json

答:这个问题问的好,这是人唯一没有参照网上资料自己根据意思研发出来的

SecurityConfig 中

.and()
    .formLogin()
    .loginPage("/login")
    .loginProcessingUrl("/loginProcessing")
    .successHandler(new AuthSeuccessHandlerController())
配置

public class AuthSeuccessHandlerController extends BaseController implements AuthenticationSuccessHandler
在 onAuthenticationSuccess 实现方法中 authentication 参数就有你的用户信息了 你不必要再去数据库查一遍了
通过reponse就可以返回json了 你可以随便折腾

配置了successHandler他就不会再重写向到项目+/了


=======================================ruo=========================================

第二部分 资源认证

当我不是用AOP架构进行认证时 就没有第二部分了


当spring security认证通过后会通过SecurityContextHolder存储在上下文之中

那么我的AOP如何才能与Authentication 进行匹配呢?答案是不可能除非重写一大堆filter

我采用的是token进行传输

我重写了restTemplate工具类 多封装了token进去了

接下来是重点:

	.authorizeRequests()
                .withObjectPostProcessor(new ObjectPostProcessor<FilterSecurityInterceptor>() {

                    @Override
                    public <O extends FilterSecurityInterceptor> O postProcess(O fsi) {
                        fsi.setAccessDecisionManager(new AccessDecisionManagerImpl(userAccountRepository));
                        /*fsi.setAuthenticationManager(authenticationManagerBean());*/
                        return fsi;
                    }
                })
//                .expressionHandler(new AbstractAuthenticationProcessingFilter())
                    .antMatchers("/").permitAll()
                    .antMatchers("/menu/root").access("ROLE_ADMIN")
这是我的认证核心,重写了FilterSecurityInterceptor,我是没有办法,因为无论是GET 还是 POST还是其它请求都无法通过 UsernamePasswordAuthenticationFilter 如果未通过 那么security会新增一个认证 那就是AnonymousAuthenticationFilter那么 Authentication 就是匿名用户了,回归正题:我们用一个类实现 AccessDecisionManager 重写decide,方法中有如下参数
Authentication authentication, Object o, Collection<ConfigAttribute> configAttributes

authentication就是认证信息, 这个咱们不用管,基本就是匿名认证用户,因为这是aop架构,o就是咱们的请求url,configAttribute就是角色信息,请参照SecurityConfig里的配置,如果我要拦截哪个路径并且只允许哪个角色访问那么这个类就包含了这些角色信息。

而为什么需要token 我们是需要往数据库里面查一遍user并且与这个configAttributes进行认证匹配的,如果匹配成功就reutrn;不成功就抛出异常。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值