为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

守着星空守着你 2023-04-19 15:05:39
不幸的是,您的解决方案没有奏效。再次抛出同样的错误。但是我最终能够确定问题所在。问题出在我的 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 不接受身份验证。我必须以某种方式继续原始登录请求并对用户进行身份验证。即使您阅读了所有这些,也非常感谢您:)
查看完整描述

1 回答

?
MMMHUHU

TA贡献1834条经验 获得超8个赞

对于遇到此问题的任何绝望的灵魂,这里是解决方案:


@RestController

public class MainLoginController {


  @RequestMapping("/manuallogin")

  ResponseEntity<Object> interceptLoginRequest ( ){

    ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();

    DefaultSavedRequest springSecuritySavedRequest = (DefaultSavedRequest) requestAttributes.getRequest()

                                                                                            .getSession()

                                                                                            .getAttribute( "SPRING_SECURITY_SAVED_REQUEST" );

    queryString = springSecuritySavedRequest.getQueryString();

    request.getSession().setAttribute( "queryString", queryString );


    return ResponseEntity.status( HttpStatus.FOUND )

                         .location( URI.create( dinosaurServer.getLoginUrl() ) )

                         .build();

  }


  @RequestMapping("/handshakeWithDinosaur")

  public ResponseEntity<Object> handshakeWithDinosaur ( String dinosaursToken ) {



    Authentication authentication = this.authenticationManager.authenticate(

        new UsernamePasswordAuthenticationToken(

            dino.getUser(), dino.getPass()

        )

    );

    SecurityContext sc = SecurityContextHolder.getContext();

    sc.setAuthentication( authentication );

    request.getSession().setAttribute( SPRING_SECURITY_CONTEXT_KEY, sc );



    String queryString = String.valueOf( request.getSession().getAttribute( "queryString" ) );


    return ResponseEntity.status( HttpStatus.FOUND )

                         .location( URI.create( String.format( "%s?%s",SPRING_AUTH_ENDPOINT, queryString ) ) )

                         .build();

  }



@Component

public class AuthProviderForDinosaur implements AuthenticationProvider {



  @Override

  public Authentication authenticate ( Authentication authentication ) throws AuthenticationException {

    List<GrantedAuthority> grantedAuths = new ArrayList<>();

    grantedAuths.add( new SimpleGrantedAuthority( "ROLE_USER" ) );

    return new UsernamePasswordAuthenticationToken( authentication.getName(), authentication.getCredentials(), grantedAuths );

  }


  @Override

  public boolean supports ( Class<? extends Object> authentication ) {

    return ( UsernamePasswordAuthenticationToken.class.isAssignableFrom( authentication ) );

  }

}

基本上,我启用了会话并让 Spring 在会话中为我保存请求,同时服务器与恐龙服务器对话并完成握手。完成后,向 Spring 询问先前请求的参数以通过 Spring Security 继续授权。


查看完整回答
反对 回复 2023-04-19
  • 1 回答
  • 0 关注
  • 79 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信