Spring Security配置:Microsoft Entra ID与用户名密码双登录及自定义登录页
Spring Security同时支持Microsoft Entra ID与用户名密码登录的问题解决
在Spring Security项目中配置了Azure AD登录按钮作为用户名密码登录的替代方案,但访问/login/oauth2/code/路径时收到未授权响应。需求是同时支持Microsoft Entra ID与用户名密码两种登录方式,使用带“使用Azure AD登录”按钮的自定义登录页,两种方式均可完成用户认证。已尝试对Microsoft Entra ID登录的基础路径设置permitAll(),但点击按钮仍报错。
核心问题与修复步骤
1. SecurityFilterChain配置遗漏OAuth2客户端支持
原配置未启用OAuth2登录功能,同时权限规则的匹配顺序和覆盖范围存在问题。需要添加oauth2Login()配置,并调整放行路径的规则:
修改后的SecurityConfig:
package com.example.AzureADTest; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.provisioning.InMemoryUserDetailsManager; import org.springframework.security.web.SecurityFilterChain; @Configuration @EnableWebSecurity public class SecurityConfig { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests(auth -> auth .requestMatchers("/login/**", "/oauth2/**").permitAll() .anyRequest().fullyAuthenticated() ) .formLogin(form -> form .loginPage("/login") .permitAll() ) .oauth2Login(oauth2 -> oauth2 .loginPage("/login") // 将自定义登录页作为OAuth2登录的入口 ); return http.build(); } @Bean public UserDetailsService userDetailsService() { UserDetails user = User.withDefaultPasswordEncoder() .username("u") .password("p") .roles("USER") .build(); return new InMemoryUserDetailsManager(user); } }
2. 自定义登录页的Azure AD按钮路径错误
原按钮使用了错误的端点(/login/oauth2/code/是回调路径,而非授权发起路径),且按钮标签使用不当。需要替换为正确的OAuth2授权端点,并使用<a>标签实现跳转:
修改后的自定义登录页面:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>New Login Page</title> </head> <body> <h1>Login Screen</h1> <div> <form name="f" th:action="@{/login}" method="post"> <fieldset> <legend>Please login</legend> <div th:if="${param.error}" class="alert alert-error"> Invalid username and password </div> <div th:if="${param.logout}" class="alert alert-success"> You have been logged out </div> <label for="username">Username</label> <input type="text" id="username" name="username"/> <label for="password">Password</label> <input type="password" id="password" name="password"/> <div class="form-actions"> <button type="submit" class="btn">Log In</button> </div> </fieldset> </form> <!-- 修正:跳转至OAuth2授权端点,默认registration ID为azuread --> <a href="/oauth2/authorization/azuread" class="btn">Login with Azure AD</a> </div> </body> </html>
3. 验证Azure AD应用注册配置
确保Azure AD应用注册中已添加正确的重定向URI:http://localhost:8080/login/oauth2/code/azuread(端口需与项目运行端口一致),同时检查application.yml中的tenant-id、client-id、client-secret是否与Azure AD应用信息完全匹配。
内容的提问来源于stack exchange,提问作者drocky
相关产品推荐
相关产品推荐

