为什么在使用 spring security 和 Kerberos 时会弹出连接?

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

我有一个使用 Kerberos 进行 sso 身份验证的 spring boot 微服务。

问题前:

当用户尝试访问应用程序(角度 UI)并遵循以下步骤时,身份验证过程开始:

  • 前端将调用 /login api(身份验证服务)。

  • 使用 Kerberos 和 spring security,我检索触发请求的用户的 id_name:

    SecurityContextHolder.getContext().getAuthentication().getName().split("@")[0]
    ,这个id_name在公司内部是独一无二的

  • 我使用这个 id_name 查询数据库并获取有关该用户的所有其他信息(无密码),然后将它们发送回前端,前端会将它们注入本地存储,因此他/她不需要连接下次再来

在我们收到更改请求以使用 JWT 来保护对我们拥有的所有微服务的访问之前,这个过程一直运行良好。

此时我添加了生成、验证令牌所需的类和拦截请求并检查令牌是否有效的过滤器...

问题:

除了一个用例外,新流程运行良好:

如果第一个连接请求是直接从前端发出的,请求会被阻止,浏览器会显示一个连接弹出窗口。否则,如果我手动调用,来自浏览器的 API 或使用邮递员,我会在响应标头中使用 Token 获得正确的结果。

注 1:如果我从浏览器手动调用 /login API,我可以像往常一样从应用程序连接,我也可以断开连接并再次连接(使用不同的配置文件..)。

注意 2:我尝试使用旧版本的 Web 服务(在添加 JWT 更改之前)并且我正确连接(令牌在请求响应中)

我在

RedirectionTokenFilter
类中添加了一些日志以获取有关请求的更多信息,在结果中我可以看到 UserPrincipal 为空,这与请求来自 Postman 时不同。

日志:

 System.out.println("UserPrincipal :" + ((HttpServletRequest) request).getUserPrincipal());
            System.out.println("Auth type :" + ((HttpServletRequest) request).getAuthType());
            System.out.println("Context path :" + ((HttpServletRequest) request).getContextPath());
            Enumeration<String> headers = ((HttpServletRequest) request).getHeaderNames();
            while(headers.hasMoreElements()){
                String param = headers.nextElement();
                System.out.println("HeaderName :" + param);
                try{
                    System.out.println("Param " +param+" :" + ((HttpServletRequest) request).getHeader(param));
                }catch (Exception e){
                }
            }
            System.out.println("Method :" + ((HttpServletRequest) request).getMethod());
            System.out.println("RemoteUser :" + ((HttpServletRequest) request).getRemoteUser());
            System.out.println("ServletPath :" + ((HttpServletRequest) request).getServletPath());

日志输出:

UserPrincipal :null
Auth type :null
Context path :/XXXX-Auth
    HeaderName :host
        Param host :XXXX:9280
    HeaderName :connection
        Param connection :keep-alive
    HeaderName :sec-ch-ua
        Param sec-ch-ua :"Chromium";v="104", " Not A;Brand";v="99", "Google Chrome";v="104"
    HeaderName :pragma
        Param pragma :no-cache
    HeaderName :sec-ch-ua-mobile
        Param sec-ch-ua-mobile :?0
    HeaderName :authorization
        Param authorization :null
    HeaderName :accept
        Param accept :application/json, text/plain,...
    HeaderName :cache-control
        Param cache-control :no-cache
    HeaderName :user-agent
        Param user-agent :Mozilla/5.0 (Windows NT 10.0; Win64; x64)....
    HeaderName :sec-ch-ua-platform
        Param sec-ch-ua-platform :"Windows"
    HeaderName :expires
        Param expires :Sat, 01 Jan 2000 00:00:00 GMT
    HeaderName :origin
        Param origin :https://XXXXXX
    HeaderName :sec-fetch-site
        Param sec-fetch-site :same-site
    HeaderName :sec-fetch-mode
        Param sec-fetch-mode :cors
    HeaderName :sec-fetch-dest
        Param sec-fetch-dest :empty
    HeaderName :referer
        Param referer :https://XXXXXX
    HeaderName :accept-encoding
        Param accept-encoding :gzip, deflate, br
    HeaderName :accept-language
        Param accept-language :en-US,en;q=0.9
Method :GET
RemoteUser :null
ServletPath :/security/login
tocken {null}
token empty trying login
context[auth]=org.springframework.security.authentication.AnonymousAuthenticationToken@274dc7e4: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@957e: RemoteIpAddress: xx.xx.xx.xx; SessionId: null; Granted Authorities: ROLE_ANONYMOUS
UserID anonymousUser
userDTO null

我的spring security配置(添加JWT后):

    @Override
    protected void configure(HttpSecurity http) throws Exception {
    
        log.info("sec configuration..");
        http.csrf().disable().cors().and().authorizeRequests().antMatchers("/**").authenticated().and().httpBasic()
                .authenticationEntryPoint(restSpenegoEntryPoint()).and()
                .addFilterBefore(spnegoAuthenticationProcessingFilter(), BasicAuthenticationFilter.class)
                .addFilterAfter(redirectionTokenFilter(), ExceptionTranslationFilter.class).addFilter(filterd)
    }

    @Bean
    public SpnegoAuthenticationProcessingFilter spnegoAuthenticationProcessingFilter() throws Exception {
        SpnegoAuthenticationProcessingFilter spnegoAuthenticationProcessingFilter = new SpnegoAuthenticationProcessingFilter();
        // spnegoAuthenticationProcessingFilter.setSuccessHandler(customAuthenticationSuccessHandler());
        spnegoAuthenticationProcessingFilter.setAuthenticationManager(authenticationManagerBean());
        return spnegoAuthenticationProcessingFilter;
    }

    @Bean
    RedirectionTokenFilter redirectionTokenFilter() {
        return new RedirectionTokenFilter();
    }

@Bean
    public CorsConfigurationSource corsConfigurationSource() {
        final CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(Collections.singletonList("*"));
        configuration.setAllowedMethods(Arrays.asList("HEAD", "GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"));
        
        configuration.setAllowedHeaders(Arrays.asList("Authorization", "Cache-Control", "Content-Type", "X-Requested-With"
                ,"Pragma","X-XSS-Protection","X-Frame-Options","X-Content-Type-Options",
                "Vary","Transfer-Encoding","Server","Expires","Date",
                "Access-Control-Allow-Headers","Access-Control-Allow-Credentials"

        ));
        configuration.setExposedHeaders(Arrays.asList("Content-type", "Authorization"));
        final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }

RestSpenegoEntryPoint

public class RestSpenegoEntryPoint extends SpnegoEntryPoint{

    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException ex)
            throws IOException, ServletException {
        response.addHeader("WWW-Authenticate", "Negotiate");
        response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
    }

}

AccessDeniedHandlerImpl

    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response,
            AccessDeniedException accessDeniedException) throws IOException, ServletException {
        response.setStatus(401);
        response.getWriter().flush();
    }

Angular 变化(我不是前端开发人员,我不太了解那些变化):

app.module.ts:

    @NgModule({
        imports: [
           providers: [
             ...
              { provide : HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi   : true},

auth-interceptor.ts:

import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Authservice } from '../service/auth.service';
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    req = req.clone({
      setHeaders: {
        'Authorization': `${Authservice.getToken()}`,
      },
    });
    return next.handle(req);
  }
}

webservice.config.ts

import {Authservice} from '../auth/service/auth.service';
export class WebServicesConfig {
@@ -11,12 +12,14 @@
        headers.append('Access-Control-Allow-Headers', 'Content-Type');
        headers.append('withCredentials', 'true');
        headers.append('Access-Control-Allow-Origin', '*');
        headers.append('Authorization', Authservice.getToken());
        return headers;
    }
    static getHeaders1(): Headers {
        let headers: Headers = new Headers();
        headers.append('Accept', 'application/json');
        headers.append('Content-Type', 'application/json');
        headers.append('Authorization', Authservice.getToken());
        return headers;
    }
}

如果有什么不清楚或缺少信息,请告诉我。

提前谢谢你。

angular authentication spring-security kerberos spnego
© www.soinside.com 2019 - 2024. All rights reserved.