猿问

使用额外回调处理自定义登录

不幸的是,您的解决方案没有奏效。再次抛出同样的错误。但是我最终能够确定问题所在。


问题出在我的 Wicket Application 类的构造函数中。在这个构造函数中,我调用了 super.init()。删除此应用程序后启动时没有 Bean 实例化错误。


public class WicketApplication extends AuthenticatedWebApplication {


//  This caused the problem with instatiating the FilterRegistrationBean    

//  public WicketApplication() {

//      super.init();

//  }


    @Override

    protected void init() {

        super.init();


        getComponentInstantiationListeners().add(new SpringComponentInjector(this));        

        mountPage("/admin", AdminPage.class);

        mountPage("/login", LoginPage.class);


    }



    @Override

    public Class<? extends Page> getHomePage() {

        return AdminPage.class;

    }



    @Override

    protected Class<? extends AbstractAuthenticatedWebSession> getWebSessionClass() {

        return AppAuthenticatedWebSession.class;

    }


    @Override

    protected Class<? extends WebPage> getSignInPageClass() {

        return LoginPage.class;

    }


    public static WicketApplication get() {

        return (WicketApplication) Application.get();

    }


}我正在使用 Spring Security 5 和 Spring Boot 2.1 构建 OAuth2 提供程序服务器。


就我而言,我的服务器必须与某些外部服务器通信以验证用户身份。这个外部服务器生活在恐龙时代,因此不使用像 OAuth 这样的通用身份验证机制。所以我必须劫持登录请求,重定向到 dinosaur 服务器,手动处理该身份验证(不幸的是,包括回调),然后返回到 spring security 以批准登录请求并确保用户获得访问令牌。


劫持登录请求如下:


@Override

  protected void configure ( HttpSecurity http ) throws Exception {

    http

        .requestMatchers()

        .antMatchers( "/login", "/oauth/authorize", "/manuallogin" )

        .and()

        .authorizeRequests()

        .anyRequest()

        .authenticated()

        .and()

        .formLogin()

        .loginPage( "/manuallogin" )

        .permitAll()

        .and().csrf().disable();


如您所见,我需要接受另一个回调,所以我丢失了原始登录请求,我无法发送响应。


我想出了以下解决方案,通过调用 OAuth2 客户端的回调 URL 来缩短。


然而,这不起作用,因为 spring 不接受身份验证。


我必须以某种方式继续原始登录请求并对用户进行身份验证。即使您阅读了所有这些,也非常感谢您:)


守着星空守着你
浏览 104回答 1
1回答

MMMHUHU

对于遇到此问题的任何绝望的灵魂,这里是解决方案:@RestControllerpublic class MainLoginController {&nbsp; @RequestMapping("/manuallogin")&nbsp; ResponseEntity<Object> interceptLoginRequest ( ){&nbsp; &nbsp; ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();&nbsp; &nbsp; DefaultSavedRequest springSecuritySavedRequest = (DefaultSavedRequest) requestAttributes.getRequest()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .getSession()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .getAttribute( "SPRING_SECURITY_SAVED_REQUEST" );&nbsp; &nbsp; queryString = springSecuritySavedRequest.getQueryString();&nbsp; &nbsp; request.getSession().setAttribute( "queryString", queryString );&nbsp; &nbsp; return ResponseEntity.status( HttpStatus.FOUND )&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.location( URI.create( dinosaurServer.getLoginUrl() ) )&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.build();&nbsp; }&nbsp; @RequestMapping("/handshakeWithDinosaur")&nbsp; public ResponseEntity<Object> handshakeWithDinosaur ( String dinosaursToken ) {&nbsp; &nbsp; Authentication authentication = this.authenticationManager.authenticate(&nbsp; &nbsp; &nbsp; &nbsp; new UsernamePasswordAuthenticationToken(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dino.getUser(), dino.getPass()&nbsp; &nbsp; &nbsp; &nbsp; )&nbsp; &nbsp; );&nbsp; &nbsp; SecurityContext sc = SecurityContextHolder.getContext();&nbsp; &nbsp; sc.setAuthentication( authentication );&nbsp; &nbsp; request.getSession().setAttribute( SPRING_SECURITY_CONTEXT_KEY, sc );&nbsp; &nbsp; String queryString = String.valueOf( request.getSession().getAttribute( "queryString" ) );&nbsp; &nbsp; return ResponseEntity.status( HttpStatus.FOUND )&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.location( URI.create( String.format( "%s?%s",SPRING_AUTH_ENDPOINT, queryString ) ) )&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.build();&nbsp; }@Componentpublic class AuthProviderForDinosaur implements AuthenticationProvider {&nbsp; @Override&nbsp; public Authentication authenticate ( Authentication authentication ) throws AuthenticationException {&nbsp; &nbsp; List<GrantedAuthority> grantedAuths = new ArrayList<>();&nbsp; &nbsp; grantedAuths.add( new SimpleGrantedAuthority( "ROLE_USER" ) );&nbsp; &nbsp; return new UsernamePasswordAuthenticationToken( authentication.getName(), authentication.getCredentials(), grantedAuths );&nbsp; }&nbsp; @Override&nbsp; public boolean supports ( Class<? extends Object> authentication ) {&nbsp; &nbsp; return ( UsernamePasswordAuthenticationToken.class.isAssignableFrom( authentication ) );&nbsp; }}基本上,我启用了会话并让 Spring 在会话中为我保存请求,同时服务器与恐龙服务器对话并完成握手。完成后,向 Spring 询问先前请求的参数以通过 Spring Security 继续授权。
随时随地看视频慕课网APP

相关分类

Java
我要回答