具有基本身份验证的 Vaadin OAuth2

问题描述 投票:0回答:1

目前我正在尝试在我的 Vaadin 应用程序中添加 OAuth 2.0,该应用程序也适用于我的登录表单。我阅读了有关为 Google 添加 OAuth 的文档

首先,我添加了所需的依赖项

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>

然后我在 application.properties 文件中为 GitHub 和 Google 添加了

client-id
client-secret

# Github
spring.security.oauth2.client.registration.github.client-id={id}
spring.security.oauth2.client.registration.github.client-secret={secret}
# Google
spring.security.oauth2.client.registration.google.client-id={id}
spring.security.oauth2.client.registration.google.client-secret={secret}

此后,我设置了我的 Web 配置文件

@Configuration
@EnableWebSecurity
public class VaadinSecurityConfiguration extends VaadinWebSecurity {

    private static final String LOGIN_URL = "/login";
    private static final String LOGIN_PROCESSING_URL = "/login";
    private static final String LOGIN_FAILURE_URL = "/login?error";
    private static final String LOGOUT_SUCCESS_URL = "/";
    private static final String DENIED_PAGE_URL = "/404";

    @Autowired
    private UserService userService;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .csrf().disable()
                .authorizeHttpRequests(auth -> {
                    auth.requestMatchers("/").permitAll();
                    auth.requestMatchers("/login").permitAll();
                    auth.requestMatchers("/register").permitAll();
                    auth.requestMatchers("/icons/**").permitAll();
                    auth.requestMatchers("/images/**").permitAll();
                    auth.requestMatchers("/oauth2/**").permitAll();
                })
                .oauth2Login(oauth -> oauth.loginPage(LOGIN_URL).permitAll())
                .formLogin(loginForm -> {
                    loginForm.loginPage(LOGIN_URL);
                    loginForm.loginProcessingUrl(LOGIN_PROCESSING_URL);
                    loginForm.failureUrl(LOGIN_FAILURE_URL);
                })
                .logout(logout -> logout.logoutSuccessUrl(LOGOUT_SUCCESS_URL))
                .exceptionHandling(e -> {
                    e.authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED));
                    e.accessDeniedPage(DENIED_PAGE_URL);
                });

        super.configure(http);
        setLoginView(http, LoginView.class);
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        super.configure(web);
    }

    @Bean
    public AuthenticationManager authenticationManager(AuthenticationConfiguration authConfiguration) throws Exception {
        return authConfiguration.getAuthenticationManager();
    }

    @Bean
    public DaoAuthenticationProvider authenticationProvider() {
        DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
        daoAuthenticationProvider.setPasswordEncoder(passwordEncoder);
        daoAuthenticationProvider.setUserDetailsService(userService);
        return daoAuthenticationProvider;
    }
}

然后登录表单

@AnonymousAllowed
@PageTitle("Login")
@Route(value = "login", layout = MainLayout.class)
public class LoginView extends VerticalLayout implements BeforeEnterObserver {

    private static final String GITHUB_OAUTH_URL = "/oauth2/code/github";
    private static final String GOOGLE_OAUTH_URL = "/oauth2/code/google";

    private final LoginForm loginForm = new LoginForm();

    public LoginView() {
        Anchor githubLoginLink = new Anchor(GITHUB_OAUTH_URL, "Login with Github");
        Anchor googleLoginLink = new Anchor(GOOGLE_OAUTH_URL, "Login with Google");
        githubLoginLink.getElement().setAttribute("router-ignore", true);
        googleLoginLink.getElement().setAttribute("router-ignore", true);

        loginForm.setAction("login");

        add(
                new H1("Welcome to Login Form"),
                loginForm,
                githubLoginLink,
                googleLoginLink
        );
    }

    @Override
    public void beforeEnter(BeforeEnterEvent beforeEnterEvent) {
        if (beforeEnterEvent.getLocation()
                .getQueryParameters()
                .getParameters()
                .containsKey("error")) {
            loginForm.setError(true);
        }
    }

}

这就是当我单击任何锚点时发生的情况。它会将我重定向到锚链接。

示例:
按下 GitHub 锚点后,它会转到

http://localhost:8080/oauth2/code/github
,我认为这不是正确的行为,因为这个

        // Set router-ignore attribute so that Vaadin router doesn't handle the login request
        githubLoginLink.getElement().setAttribute("router-ignore", true);
        googleLoginLink.getElement().setAttribute("router-ignore", true);

取自 Vaadin 官方文档。在此重定向页面上,如果不发生 OAuth,则不会发生任何事情。希望有人能帮忙解决这个问题,干杯!

java spring-boot authentication oauth-2.0 vaadin
1个回答
0
投票

您定义了两种不同的

SecurityFilterChain
beans:一种带有
Basic
auth,另一种带有
oauth2client()
oauth2Login()

这两个安全过滤器链必须用

@Order
修饰以确定首先尝试哪个。

第一个尝试的必须有一个

securityMatcher
来定义它适用于哪些请求。在您的情况下,以
Authorization
开头的
Basic 
标题上的匹配器似乎是一个不错的候选者。

@Bean
@Order(Ordered.LOWEST_PRECEDENCE - 1)
SecurityFilterChain basicAuthFilterChain(HttpSecurity http) throws Exception {

    // process only requests with HTTP Basic Authorization
    http.securityMatcher((HttpServletRequest request) -> {
        return Optional.ofNullable(request.getHeader(HttpHeaders.AUTHORIZATION)).map(h -> {
            return h.toLowerCase().startsWith("basic ");
        }).orElse(false);
    });

    http.httpBasic(withDefaults());

    ...

    return http.build();
}

@Bean
@Order(Ordered.LOWEST_PRECEDENCE)
SecurityFilterChain oauth2ClientFilterChain(HttpSecurity http) throws Exception {
    http.oauth2Client(withDefaults());
    http.oauth2Login(withDefaults());

    ...

    return http.build();
}
© www.soinside.com 2019 - 2024. All rights reserved.