栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Spring Security Oauth2自定义登录简单实现

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Spring Security Oauth2自定义登录简单实现

 参考文章Spring Security Oauth2关于自定义登录的几种解决方案(一)_小丑竟是我自己-CSDN博客

初衷

由于oauth2默认提供的password模式需要client_id,秘钥,grant_type,用户名,密码这几个参数才可以进行登录验证。

有没有一种方式,只输入用户名,密码就能登录的呢?

代码实现

目录

初衷

代码实现

新建用户名密码权限认证类

新建oauth核心配置类

新建登录方法

配置客户端

测试

总结


导入oauth包



	4.0.0

	com.itcv.spring.oauth.demo
	spring-oauth-demo
	1.0-SNAPSHOT

	
		org.springframework.boot
		spring-boot-starter-parent
		2.2.10.RELEASE
		 
	



	
		org.springframework.boot
		spring-boot-starter-actuator
	
	
		org.springframework.boot
		spring-boot-starter-web
	
	
		org.springframework.boot
		spring-boot-starter-freemarker
		2.3.12.RELEASE
	

	
	
	
		org.springframework.cloud
		spring-cloud-starter-oauth2
		2.2.0.RELEASE
		
			
			
				spring-security-oauth2
				org.springframework.security.oauth
			
		
	
	
		org.springframework.security.oauth
		spring-security-oauth2
		2.3.8.RELEASE
	
	
		com.alibaba
		fastjson
		1.2.78
	
	
		org.projectlombok
		lombok
	


 

新建用户名密码权限认证类
@Component
public class AdminPwdAuthenticationProvider implements AuthenticationProvider {
​
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private UserDetailsService userDetailsService;
​
    //认证方法
    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        UsernamePasswordAuthenticationToken adminLoginToken = (UsernamePasswordAuthenticationToken) authentication;
        System.out.println("===进入Admin密码登录验证环节====="+ JSON.toJSonString(adminLoginToken));
        UserDetails userDetails = userDetailsService.loadUserByUsername(adminLoginToken.getName());
        //matches方法,前面为明文,后续为加密后密文
        //匹配密码。进行密码校验
        if(passwordEncoder.matches(authentication.getCredentials().toString(),userDetails.getPassword())){
            return  new UsernamePasswordAuthenticationToken(userDetails, userDetails.getPassword(), userDetails.getAuthorities());
        }
        throw  new BadCredentialsException("用户名密码不正确");
    }
    @Override
    public boolean supports(Class authentication) {
        return UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication);
    }
}

新建oauth核心配置类
@Configuration
@EnableWebSecurity
@EnableAuthorizationServer //这个配置是必须加的,不加的话,接下来使用TokenEndpoint会提示找不到对应的类
public class SecurityConfig extends WebSecurityConfigurerAdapter {
​
    private static final String[] excludedAuthPages = {"/login/**",};
    @Override
    @Bean(name = BeanIds.AUTHENTICATION_MANAGER)
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }
​
    @Bean
    public PasswordEncoder passwordEncoder() {
        return PasswordEncoderFactories.createDelegatingPasswordEncoder();
    }
​
    @Bean
    @Override
    //模拟用户
    public UserDetailsService userDetailsService() {
        // 测试方便采用内存存取方式
        InMemoryUserDetailsManager userDetailsService = new InMemoryUserDetailsManager();
        userDetailsService.createUser(User.withUsername("user_1").password(passwordEncoder().encode("123456")).authorities("ROLE_USER").build());
        userDetailsService.createUser(User.withUsername("user_2").password(passwordEncoder().encode("1234567")).authorities("ROLE_USER").build());
        return userDetailsService;
    }
​
​
    @Autowired
    private AdminPwdAuthenticationProvider adminPwdAuthenticationProvider;
​
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //此处注入一个默认的service,也可以不注入,我做测试时使用,根据需求,该service非admin-userservice
        auth.userDetailsService(userDetailsService());
        //添加两个Provider
       // auth.authenticationProvider(adminSmsAuthenticationProvider);
        auth.authenticationProvider(adminPwdAuthenticationProvider);
    }
​
    //安全拦截机制(最重要)
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.headers().contentTypeOptions().disable()
                .frameOptions().sameOrigin()
                .and()
                .authorizeRequests()
                .antMatchers(excludedAuthPages).permitAll()
                .antMatchers(HttpMethod.OPTIONS).permitAll()
                .requestMatchers(EndpointRequest.toAnyEndpoint()).permitAll()
                .and().authorizeRequests()
                .anyRequest().authenticated()
                .and().formLogin().disable()
                .exceptionHandling()
                .and().csrf().disable()
                .logout().disable().authorizeRequests();
    }
}

新建登录方法
@RestController
@RequestMapping("/")
public class LoginController {
​
    @Autowired
    private OAuth2ClientProperties oauth2ClientProperties;
    @Autowired
    private TokenEndpoint tokenEndpoint;
​
    @PostMapping("/login/admin")
    public OAuth2AccessToken adminLogin(@RequestBody UserRequest request) throws HttpRequestMethodNotSupportedException {
        //创建客户端信息,客户端信息可以写死进行处理,因为Oauth2密码模式,客户端双信息必须存在,所以伪装一个
        //如果不想这么用,需要重写比较多的代码
        User  clientUser= new User(oauth2ClientProperties.getClientId(),oauth2ClientProperties.getClientSecret(), new ArrayList<>());
        //生成已经认证的client
        UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(clientUser,null, new ArrayList<>());
        Map parameters = new HashMap();
        //封装成一个UserPassword方式的参数体,放入手机号
        parameters.put("username", request.getPhone());
        //放入验证码
        parameters.put("password", request.getVcode());
        //授权模式为:密码模式
        parameters.put("grant_type", "password");
        //调用自带的获取token方法。
        OAuth2AccessToken oAuth2AccessToken = tokenEndpoint.postAccessToken(token, parameters).getBody();
        return oAuth2AccessToken;
    }

配置客户端
security:
  oauth2:
    client:
      clientId: demoApp
      clientSecret: 123456
      scope: ALL
      authorized-grant-types: password,refresh_token

测试

访问自定义登录接口,输入用户名,密码可以正常登录

 

访问oauth2自带登录接口

 

 

总结

违背了初衷,原本想着是两个都可以正常使用的;oauth2自带的登录接口也走到了自定义的类里边。

源码地址

spring-security-demo: spring-sevurity入门实例

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/341137.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号