我们系统是Spring Security,然后要跟第三方对接统一登录,用的aouth2授权模式,我们这边只做回调处理.
授权服务器跳转到我们系统之后,进行账号校验存在的话,直接进入系统吗?如果直接进入系统,redis中的token又是怎样存进去的?
我想的是我们系统内部应该要再登录一次,然后登录的话,需要账号密码,但是拿不到密码.只能新写一个登录接口,只需要账号就能登录.
新写登录接口,还得用Spring Security原有的登录逻辑,原来的登录和新的登录需要并存,目前情况就是这样,各位有没有什么思路
![](https://profile-avatar.csdnimg.cn/default.jpg!4)
Spring Security登录问题
- 写回答
- 好问题 0 提建议
- 追加酬金
- 关注问题
- 邀请回答
-
4条回答 默认 最新
关注
引自免费微信小程序:皆我百晓生
在Spring Security中实现OAuth2的集成,并且需要支持账号校验和令牌存储,我们可以按照以下步骤进行操作。
- 配置OAuth2客户端
首先,你需要配置OAuth2客户端,这通常在
application.yml
或application.properties
文件中完成。例如:spring: security: oauth2: client: registration: third_party: clientId: your_client_id clientSecret: your_client_secret provider: third_party_provider redirectUriTemplate: "{baseUrl}/login/oauth2/code/{registrationId}" provider: third_party_provider: authorization-uri: https://third-party.com/oauth/authorize token-uri: https://third-party.com/oauth/token user-info-uri: https://third-party.com/userinfo jwk-set-uri: https://third-party.com/jwks
- 添加必要的依赖
确保你的项目包含以下依赖项(如果你还没有添加):
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.security.oauth.boot</groupId> <artifactId>spring-security-oauth2-autoconfigure</artifactId> </dependency>
- 实现OAuth2登录回调处理
创建一个控制器来处理OAuth2的回调请求。在这个控制器里,你会从OAuth2提供商那里获取用户信息并验证它。
@Controller public class OAuth2CallbackController { @Autowired private UserDetailsService userDetailsService; @Autowired private AuthenticationManager authenticationManager; @RequestMapping(value = "/login/oauth2/code/{registrationId}") public String processAuthorizationCode( @PathVariable("registrationId") String registrationId, RedirectAttributes attributes, OAuth2AuthenticationToken auth) { // 获取用户信息 Principal principal = auth.getUserAuthentication().getPrincipal(); // 根据principal获取UserDetails对象 UserDetails userDetails = userDetailsService.loadUserByUsername(principal.getName()); // 使用Spring Security的登录逻辑进行登录 UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities()); try { authenticationManager.authenticate(token); } catch (AuthenticationException e) { throw new RuntimeException(e.getMessage(), e); } SecurityContextHolder.getContext().setAuthentication(token); // 将用户信息保存到Redis saveTokenToRedis(userDetails, auth); return "redirect:/"; // 返回应用首页 } private void saveTokenToRedis(UserDetails userDetails, OAuth2AuthenticationToken auth) { // 这里是一个示例,实际操作可能需要根据你的Redis配置进行调整 RedisTemplate<String, OAuth2AccessToken> redisTemplate = new StringRedisTemplate(); String key = "user:" + userDetails.getUsername(); redisTemplate.opsForValue().set(key, auth.getAccessToken().getValue()); } }
- 自定义登录接口
为了支持仅凭用户名登录,你需要创建一个新的登录接口。这里可以使用JWT作为令牌,因为OAuth2本身已经处理了大部分安全方面的工作。
@RestController @RequestMapping("/api/login") public class CustomLoginController { @Autowired private UserRepository userRepository; @Autowired private JwtService jwtService; @PostMapping("/username") public ResponseEntity<?> login(@RequestBody LoginRequest request) { User user = userRepository.findByUsername(request.getUsername()); if (user == null || !passwordEncoder().matches(request.getPassword(), user.getPassword())) { throw new ResourceNotFoundException("Invalid credentials"); } // 生成JWT令牌 String accessToken = jwtService.generateToken(user); // 返回响应体 return ResponseEntity.ok(new JwtResponse(accessToken)); } } // 响应模型类 class JwtResponse { private final String accessToken; public JwtResponse(String accessToken) { this.accessToken = accessToken; } // getters and setters } // 请求模型类 class LoginRequest { private String username; private String password; // getters and setters }
- Spring Security配置
确保Spring Security配置正确地处理了这些端点和认证过程。在你的
SecurityConfig.java
中,添加以下内容:@Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private CustomAuthenticationProvider customAuthenticationProvider; @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/login/**").permitAll() .anyRequest().authenticated() .and() .oauth2Login() .redirectionEndpointrediRectUriTemplate("/{registrationId}/callback") .and() .logout().logoutSuccessUrl("/") .and() .csrf().disable(); // 如果使用JWT,可能需要禁用CSRF保护 } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.authenticationProvider(customAuthenticationProvider); } }
- 自定义AuthenticationProvider
创建一个自定义的
AuthenticationProvider
,以便在调用customAuthenticationProvider.authenticate()
时,使用CustomLoginController
提供的用户名登录功能。@Service public class CustomAuthenticationProvider implements AuthenticationProvider { @Autowired private UserRepository userRepository; @Override public Authentication authenticate(Authentication authentication) throws AuthenticationException { String name = authentication.getName(); String password = authentication.getCredentials().toString(); User user = userRepository.findByUsername(name); if (user != null && passwordEncoder().matches(password, user.getPassword())) { return new UsernamePasswordAuthenticationToken(user, password, user.getAuthorities()); } throw new BadCredentialsException("Invalid credentials"); } @Override public boolean supports(Class<?> authentication) { return authentication.equals(UsernamePasswordAuthenticationToken.class); } }
以上代码示例展示了如何实现OAuth2登录与基于用户名的登录功能。你可能需要根据实际情况对代码进行一些调整,比如数据库访问、加密方法等。同时,确保你的Redis服务器已启动,并且连接配置正确。
本回答被专家选为最佳回答 , 对您是否有帮助呢?解决 无用评论 打赏 举报 编辑记录
悬赏问题
- ¥15 llama3中文版微调
- ¥15 时间序列预测算法 预测结果出现负值
- ¥15 在win系统Django虚拟环境下载mysqlclient报错
- ¥15 pg数据库导入数据序列重复
- ¥15 三分类机器学习模型可视化分析
- ¥15 本地测试网站127.0.0.1 已拒绝连接,如何解决?(标签-ubuntu)
- ¥50 Qt在release捕获异常并跟踪堆栈(有Demo,跑一下环境再回答)
- ¥30 python,LLM 文本提炼
- ¥15 关于将inet引入的相关问题
- ¥15 关于一个倒计时的操作和显示设计