You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 21:14:58