【问题标题】:How can I correctly configure redirects in Spring Security with a Vue.js Frontend to work with OAuth2.0?如何使用 Vue.js 前端在 Spring Security 中正确配置重定向以使用 OAuth2.0?
【发布时间】:2019-11-07 17:03:00
【问题描述】:

我们有一个用例,用户在每封电子邮件中都会收到一个链接。例如以下链接:

http://localhost:8080/#approveData?uploadId=134

只要用户已经使用我们基于 OAuth2 的 SSO 登录,这将正常工作。但是,在我们需要对用户进行身份验证和授权的情况下,我无法使重定向正常工作。

第一个问题是去这个页面和去的效果一模一样

http://localhost:8080/

单击邮件中的链接或直接进入“/”处的应用程序主页只会导致 403,并且不会成功重定向到 Auth Server 的登录页面。

如果我导航到http://localhost:8080/login/,我会正确重定向到在 localhost:9000 上运行的身份验证服务器。我可以登录,但随后我被发送到 http://localhost:8080/#/ 路径,该路径现在可以正确加载,但我希望自动重定向到以下页面

http://localhost:8080/#approveData?uploadId=134

我使用 Spring Boot 作为 OAuth2 客户端和 Vue.js 作为前端。

下面是相关的Spring配置:

@EnableOAuth2Client
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

@Autowired
OAuth2ClientContext oauth2ClientContext;

@Override
protected void configure(HttpSecurity http) throws Exception {

    http.authorizeRequests().anyRequest().authenticated().and().addFilterBefore(ssoFilter(),
            BasicAuthenticationFilter.class);
    http.csrf().disable();

}

private Filter ssoFilter() {

    OAuth2ClientAuthenticationProcessingFilter webEamFilter = new OAuth2ClientAuthenticationProcessingFilter("/login");
    OAuth2RestTemplate webEamTemplate = new OAuth2RestTemplate(webEamNext(), oauth2ClientContext);
    webEamFilter.setRestTemplate(webEamTemplate);
    UserInfoTokenServices tokenServices = new UserInfoTokenServices(
            webEamNextResource().getUserInfoUri(),
            webEamNext().getClientId());
    tokenServices.setRestTemplate(webEamTemplate);
    webEamFilter.setTokenServices(tokenServices);



    return webEamFilter;
}

@Bean
@ConfigurationProperties("webeamnext.client")
public AuthorizationCodeResourceDetails webEamNext() {

    return new AuthorizationCodeResourceDetails();
}

@Bean
@ConfigurationProperties("webeamnext.resource")
public ResourceServerProperties webEamNextResource() {
    return new ResourceServerProperties();
}

@Bean
public PrincipalExtractor webEamNextPrincipalExtractor() {
    return new WebEamNextPrincipalExtractor();
}

@Bean
public FilterRegistrationBean<OAuth2ClientContextFilter> oauth2ClientFilterRegistration(
        OAuth2ClientContextFilter filter) {

    FilterRegistrationBean<OAuth2ClientContextFilter> registration = new FilterRegistrationBean<>();
    registration.setFilter(filter);
    registration.setOrder(-100);
    return registration;
}

@Bean
public CommonsRequestLoggingFilter requestLoggingFilter() {
    CommonsRequestLoggingFilter loggingFilter = new CommonsRequestLoggingFilter();
    loggingFilter.setIncludeClientInfo(true);
    loggingFilter.setIncludeQueryString(true);
    loggingFilter.setIncludePayload(true);
    return loggingFilter;
}

}

这是我的应用程序属性文件:

##Oauth Settings
security.basic.enabled=false
webeamnext.client.accessTokenUri=http://localhost:9000/auth/oauth/token
webeamnext.client.clientId=SampleClientId
webeamnext.client.clientSecret=secret
webeamnext.client.userAuthorizationUri=http://localhost:9000/auth/oauth/authorize
webeamnext.resource.userInfoUri=http://localhost:9000/auth/user/me

在我看来,spring 完全不知道 Vue.js 组件或 URL,它认为唯一的 URL 是 /。 # 之后的 URL 的所有其他部分仅存在于 Vue.js 的世界中

这是我的 Vue.js 路由器:

import Vue from 'vue'
import Router from 'vue-router'
import openCalculation from '@/components/openCalculation.vue'
import checkoutData from '@/components/checkoutData.vue'
import appProCircle from '@/components/appProCircle.vue'
import appBDchange from '@/components/appBDchange.vue'
import testDB from '@/components/testDB.vue'
import approveData from '@/components/approveData.vue'

Vue.use(Router)

export default new Router ({

    routes: [
        {
            path: '/',
            name: 'appProCircle',
            component: appProCircle,
        },

        {
            path: '/openCalculation',
            name: 'OpenCalculation',
            component: openCalculation,
            props: true
        },
        {
            path:'/checkoutData',
            name:'CheckoutData',
            component: checkoutData,

        },

        {
            path: '/testDB',
            name: 'testDB',
            component: testDB
        },

        {
            path: '/approveData',
            name: 'ApproveData',
            component: approveData
        },

    ]
})

【问题讨论】:

    标签: spring-boot vue.js spring-security oauth-2.0


    【解决方案1】:

    您只需要为应用程序创建一个拦截器。

    这里是拦截器外观的快速草图,

    @Component
    public class SecurityProtection extends HandlerInterceptorAdapter {
    
        public static final String SESSION_USER = "SESSION_USER";
        private Logger logger = LoggerFactory.getLogger(this.getClass());
    
        public SecurityProtection() {
        }
    
        @PostConstruct
        public void init() {
        }
    
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            if (null == request.getSession().getAttribute(SESSION_USER)) {
                String redirectURL = "/login";
                response.sendRedirect(redirectURL);
                return false;
            }
            return super.preHandle(request, response, handler);
        }
    
    }
    

    然后不要忘记包含在您的安全配置中。

    @Configuration
    public class SecurityConfig implements WebMvcConfigurer {
    
        @Autowired
        private SecurityProtection securityProtection;
    
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(securityProtection);
        }
    
    }
    

    【讨论】:

    • 这有点用,但问题是当我粘贴 URL localhost:8080/#approveData?uploadId=134 时,我无法弄清楚如何在“#”符号后面获取请求部分。前端是基于 Vue.js 的单页应用程序。 #approveData 组件是一个 vue 组件,整个应用程序位于 Spring 中的“/”路径上。是否可以从“HttpServletRequest 请求”中获取“#”之后的部分。谢谢
    • 不幸的是,# 之后的部分仅对浏览器可用,对服务器端的 Spring Boot 不可用。在这种情况下,我建议您使 index.html 和 angular 的其他静态内容未经身份验证。让 Angular 启动通过调用 API 来检查经过身份验证的会话,如果失败,则将 location.href 值设置为 sessionStorage 并将用户重定向到登录页面。成功登录后,通过重置sessionStorage 的值将用户重定向回#part 我建议您阅读stackoverflow.com/a/23784932/3560866
    猜你喜欢
    • 2020-12-20
    • 2019-10-18
    • 1970-01-01
    • 2014-08-30
    • 2011-12-05
    • 2016-03-07
    • 2018-10-02
    • 2022-12-04
    • 1970-01-01
    相关资源
    最近更新 更多