终于拿回账号密码了

MD,吐下槽

好久没来了,现在技术发展太快,本来不想再写博了,后来看到很多写人生的技术牛人,回看自己的coding路,再加上带的团队越来越大,人数越来越多,所以也想写点什么,总结当下,展望未来。

重回优快云,我就之前那次泄漏事件改过一次密码,但怎么都登录不上,通过邮箱找回密码吧,那邮箱的服务商竟然终止服务了,好在客服通情达理,很快就找回密码了,只不过登录要绑定手机号,说是根据《互联网用户账号名称管理规定》,但我看了相关链接,并没发现需要绑定手机的,这也算了,还要关注公众号,我去,这手段吸粉我也是醉了。

不管怎么说,终究还是能登录了

在你的前后端分离系统中(前端 Vue2 + 后端 Spring Security),要接入 **Azure AD** 实现单点登录(SSO),你需要将传统的账号密码登录改为基于 **OAuth 2.0 / OpenID Connect (OIDC)** 的认证流程。Azure AD 是一个成熟的 OAuth 2.0 和 OIDC 提供商。 以下是完整的实现方案,包括配置、代码示例和流程说明。 --- ## ✅ 实现目标 - 用户点击“登录”按钮后跳转到 Azure AD 登录页面。 - 登录成功后,Azure AD 返回 ID Token 和 Access Token。 - 前端获取 token 并传给后端。 - 后端使用 Spring Security 验证 JWT token 的合法性(无需查库)。 - 认证通过后允许访问受保护资源。 --- ## 🔧 整体架构流程 ``` Vue2 Frontend ──(重定向)──> Azure AD Login ──(回调)──> /login/oauth2/code/azure ↓ Spring Security 处理回调,验证 JWT ↓ 生成内部 session 或返回 JWT ↓ 前端保存 token,后续请求带 Token ``` --- ## 步骤一:在 Azure AD 中注册应用 1. 登录 [Azure Portal](https://portal.azure.com/) 2. 进入 **Azure Active Directory > App registrations > New registration** 3. 填写: - Name: `my-vue-spring-app` - Supported account types: 可选 - Redirect URI: - 类型选 **Web** - 值为:`http://localhost:8080/login/oauth2/code/azure` (这是 Spring 默认的 OAuth2 回调地址) 4. 注册完成后记下: - **Application (client) ID** - **Directory (tenant) ID** 5. 在 “Certificates & secrets” 中新建一个 Client Secret,保存其值(只能看一次) 6. 配置权限(API Permissions): - 添加 `openid`, `profile`, `email`, `offline_access` --- ## 步骤二:Spring Boot 后端配置(Spring Security + OAuth2 Login) ### 1. 添加依赖(Maven) ```xml <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-oauth2-client</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies> ``` ### 2. 配置 `application.yml` ```yaml spring: security: oauth2: client: registration: azure: client-id: your-client-id client-secret: your-client-secret tenant-id: your-tenant-id provider: azure scope: openid,profile,email redirect-uri: "{baseUrl}/login/oauth2/code/{registrationId}" authorization-grant-type: authorization_code provider: azure: issuer-uri: https://login.microsoftonline.com/${spring.security.oauth2.client.registration.azure.tenant-id}/v2.0 server: port: 8080 ``` > ⚠️ 替换 `your-client-id`, `your-client-secret`, `your-tenant-id` ### 3. 配置 Spring Security ```java @Configuration @EnableWebSecurity public class SecurityConfig { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests(authz -> authz .requestMatchers("/login**", "/error**").permitAll() .anyRequest().authenticated() ) .oauth2Login(oauth2 -> oauth2 .defaultSuccessUrl("/index.html", true) // 登录成功跳转到前端首页 ) .logout(logout -> logout .logoutSuccessUrl("/").permitAll() ); return http.build(); } } ``` > 注意:如果你希望返回 JSON 而不是跳转页面(更适合前后端分离),需要自定义 `AuthenticationSuccessHandler`。 --- ## ✅ 自定义 Success Handler(推荐用于前后端分离) 为了让前端能拿到 token 并控制跳转,我们返回 JSON 而非重定向。 ### 自定义 OAuth2 登录成功处理器 ```java @Component public class OAuth2AuthenticationSuccessHandler implements AuthenticationSuccessHandler { @Override public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { OAuth2User oAuth2User = (OAuth2User) authentication.getPrincipal(); String idToken = ((DefaultOAuth2AccessToken) ((OAuth2AuthenticationToken) authentication) .getAccessToken()).getTokenValue(); // 构造响应 JSON ObjectMapper mapper = new ObjectMapper(); Map<String, Object> data = new HashMap<>(); data.put("user", oAuth2User.getAttributes()); data.put("id_token", idToken); data.put("access_token", ((OAuth2AccessToken) ((OAuth2AuthenticationToken) authentication).getAccessToken()).getTokenValue()); response.setContentType("application/json;charset=UTF-8"); response.getWriter().write(mapper.writeValueAsString(data)); } } ``` ### 修改 SecurityConfig 使用该 handler ```java @Autowired private OAuth2AuthenticationSuccessHandler successHandler; @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests(authz -> authz .requestMatchers("/login**", "/error**").permitAll() .anyRequest().authenticated() ) .oauth2Login(oauth2 -> oauth2 .successHandler(successHandler) ) .csrf().disable() .cors(); // 启用 CORS return http.build(); } ``` > 别忘了配置 CORS 支持: ```java @Bean public CorsConfigurationSource corsConfigurationSource() { CorsConfiguration config = new CorsConfiguration(); config.setAllowedOriginPatterns(Arrays.asList("*")); config.setAllowedMethods(Arrays.asList("GET", "POST", "OPTIONS")); config.setAllowedHeaders(Arrays.asList("*")); config.setAllowCredentials(true); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/login/oauth2/code/*", config); return source; } ``` --- ## 步骤三:前端 Vue2 接入 ### 1. 登录按钮触发跳转 ```html <template> <div> <button @click="loginWithAzure">使用 Azure 登录</button> </div> </template> <script> export default { methods: { loginWithAzure() { window.location = 'http://localhost:8080/oauth2/authorization/azure'; } } } </script> ``` > Spring Boot 会自动暴露 `/oauth2/authorization/azure` 路由,触发 OAuth2 流程。 ### 2. 获取用户信息(通过后端接口) 你可以在登录成功后让后端返回用户数据,或者前端从 ID Token 解码用户信息(不推荐自行解析,建议走后端校验)。 ### 3. 存储 Token(可选) 如果后端返回了 JWT token,你可以将其存储在 `localStorage` 或 Vuex,并在后续请求中添加: ```js axios.defaults.headers.common['Authorization'] = 'Bearer ' + token; ``` --- ## ✅ 可选增强功能 | 功能 | 说明 | |------|------| | JWT 校验 | Spring Security 默认会自动验证 Azure 签发的 JWT 是否合法(issuer, signature, expiration) | | 用户映射 | 使用 `OAuth2UserService` 加载本地用户信息或创建新用户 | | 前端库替代手动跳转 | 使用 MSAL.js(如 `msal-browser`)直接在前端处理登录,但需配合后端验证 token | > ⚠️ 若使用 MSAL.js 直接获取 token,后端仍需独立验证 JWT 的有效性(防止伪造) --- ## 📌 总结:你现在拥有了什么? - 用户可通过 Azure AD 登录系统 - Spring Security 完成 OAuth2 登录流程 - 登录成功返回 JSON 包含用户信息和 token - 前端可接管后续流程 --- ## ❓常见问题与排查 - **回调地址不匹配?** → 检查 Azure 中注册的 redirect URI 是否与 Spring 中一致 - **Invalid redirect_uri?** → 确保是 `http://localhost:8080/login/oauth2/code/azure` - **401 Unauthorized?** → 检查 token 是否过期,或未正确传递 - **CSRF 问题?** → 前后端分离建议关闭 CSRF(仅适用于无 session 场景)或启用 CORS + SameSite ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值