Spring Security实现代码自动登录(一)

由于最近项目需要使用activiti工作流,activiti7中使用SpringSecurity安全框架。但是项目的业务场景是不涉及登录,登录在统一权限系统中。
任务要求是用户访问系统发送请求时带了token,不需要将页面跳转到登录页面进行登录,直接通过请求时的用户信息进行登录Spring Security验证用户信息。
网上大部分资料都是spring security配置资料中都涉及登录页面的的登录,基本上没有这块资料。中间发现很多坑,自己在此记录一下。
自己的项目框架如下:
1.springboot 2.2.1.RELEASE
2.activiti 7.1.0.M1
3.数据库mysql

参考自己之前地址:项目配置链接
一、创建拦截
创建SessionInterceptorConfig和MyInterceptor 两个类
SessionInterceptorConfig代码如下:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class SessionInterceptorConfig implements WebMvcConfigurer {

    @Autowired
    private MyInterceptor sessionInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 配置会话拦截器,不拦截应用登录入口和应用注销入口
        registry.addInterceptor(sessionInterceptor).addPathPatterns("/**")
				.order(Ordered.HIGHEST_PRECEDENCE);
    }
}

MyInterceptor 代码如下

@Component
public class MyInterceptor implements HandlerInterceptor {
	 @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object apiResponsehandler)
            throws Exception {
        		//截取请求header中token,解析用户信息业务代码不做粘贴
                //以下做springSecurity
                //通过token 兑换用户信息 将用户名和密码生成可用的AuthenticationToken 
                //这是SpringSecurity的
                UsernamePasswordAuthenticationToken springSecurityAuthToken = new UsernamePasswordAuthenticationToken(user.getUserLoginName(), user.getUserLoginName());
                //确保request 中有sessionId
                String sessionId = request.getSession().getId();
                logger.info("sessionId=="+sessionId);
                //设置AuthenticationToken 的userDetails主要获取请求中一些参数信息
                //注意该方法request中必须有session信息否则会报错
                springSecurityAuthToken.setDetails(new WebAuthenticationDetails(request));
                //用户信息Token完成SpringSecurity认证获得认证对象
                Authentication authenticatedUser = authenticationManager.authenticate(springSecurityAuthToken);
                //将用户存放到安全框架SecurityContext中
                SecurityContextHolder.getContext().setAuthentication(authenticatedUser);
                //SecurityContext context = SecurityContextHolder.getContext();
                request.getSession().setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, SecurityContextHolder.getContext());
                Object attribute = request.getAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);            
                return true;
            } catch (Exception e) {
                e.printStackTrace();  
            }
        }
        return false;
    }
}

只配置这些启动还是有问题,会出现401
二、自定义 Spring Boot Web 安全配置类
创建SecurityConfig类
代码如下:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

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

        http.authorizeRequests()
                .anyRequest().permitAll().and().logout().permitAll()//配置不需要登录验证
                .and().headers().frameOptions().sameOrigin()// 解决  frame because it set 'X-Frame-Options' to 'deny'
                .and().cors() //允许跨域
                .and().csrf().disable() //关闭跨站请求伪造
        ;
    }
    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        AuthenticationManager manager = super.authenticationManagerBean();
        return manager;
    }

    @Bean
    @Override
    protected UserDetailsService userDetailsService(){
        //采用一个自定义的实现UserDetailsService接口的类
        return new MyUserDetailServiceImpl();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth)
            throws Exception {
        auth.authenticationProvider(authenticationProvider());
    }

    @Bean
    public DaoAuthenticationProvider authenticationProvider() {
        DaoAuthenticationProvider authProvider
                = new DaoAuthenticationProvider();
        authProvider.setUserDetailsService(userDetailsService());
        authProvider.setPasswordEncoder(encoder());
        return authProvider;
    }
	
	//默认是BCryptPasswordEncoder 加密 但是业务已经不需要再做密码要求,必须采用统一权限系统解密方式不现实,改为NoOpPasswordEncoder 否则报密码方式问题
    @Bean
    public PasswordEncoder encoder() {
        return NoOpPasswordEncoder.getInstance();
    }
}

创建UserDetailsService实现类 (必须)
代码如下:

/**
 *
 * 自定义实现SpringSecurity 中的UserDetailsService接口
 * @author jiaoda
 * @version 1.0
 */
@Service
public class MyUserDetailServiceImpl implements UserDetailsService {

    @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
        //这里通过用户名查询用户信息
        System.out.println("s==="+s);
       //自己实现代码
        return new MyUserPrincipal(contextUser);
    }
}

创建MyUserPrincipal实现类
代码如下:

/**
 *
 * 自定义实现SpringSecurity 中的UserDetails接口
 * @author jiaozhicong
 * @version 1.0
 */

public class MyUserPrincipal implements UserDetails {

    public ContextUser user;

    public MyUserPrincipal(ContextUser user) {
        this.user = user;
    }


    public ContextUser getUser() {
        return user;
    }

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

    @Override
    public String getPassword() {
        return user.getUserLoginName();
    }

    @Override
    public String getUsername() {
        return user.getUserName();
    }
	//默认false
	/*
	*必须改为true 否则用户无效
	*/
    @Override
    public boolean isAccountNonExpired() {
        return true;
    }
    /*
	*必须改为true 否则用户无效
	*/
	//默认false
    @Override
    public boolean isAccountNonLocked() {
        return true;
    }
    /*
	*必须改为true 否则用户无效
	*/
	//默认false
    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }
    /*
	*必须改为true 否则用户无效
	*/
	//默认false
    @Override
    public boolean isEnabled() {
        return true;
    }
}

到此为止,在启动项目测试不会出现问题。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值