带有spring-boot安全休息api的角度2
Posted
技术标签:
【中文标题】带有spring-boot安全休息api的角度2【英文标题】:angular 2 with spring-boot security rest api 【发布时间】:2017-08-19 16:20:15 【问题描述】:我正在开发一个 web 应用程序,它的前端是用 Angular2 (typescript) 编写的,它是从 angular cli 和 Spring Boot 1.5.2 RELEASE 生成的。由于我想要解耦工作,因此我将 REST 部署在 Tomcat(localhost:8084 with contextpath app-api
)和 angular cli(localhost:4200)上的前端。
我登录后调用其他api时出现问题,但结果是401。登录成功后没有保留JSessionId并发送第二个请求的标头。
这是我的 bean 配置:
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd">
<global-method-security />
<beans:bean id="failureHandler" class="my.app.auth.RESTAuthenticationFailureHandler"></beans:bean>
<beans:bean id="successHandler" class="my.app.auth.RESTAuthenticationSuccessHandler"></beans:bean>
<beans:bean id="loginUrlAuthenticationEntryPoint" class="my.app.auth.RESTAuthenticationEntryPoint"></beans:bean>
<beans:bean id="loginPathRequestMatcher" class="org.springframework.security.web.util.matcher.AntPathRequestMatcher">
<beans:constructor-arg type="java.lang.String" value="/login" />
</beans:bean>
<beans:bean id="customUsernamePasswordAuthenticationFilter"
class="my.app.auth.AuthenticationFilter">
<beans:constructor-arg ref="loginPathRequestMatcher"/>
<beans:constructor-arg ref="environment"/>
<beans:constructor-arg ref="httpClient"/>
<beans:property name="authenticationManager" ref="authenticationManager" />
<beans:property name="sessionAuthenticationStrategy" ref="session-management" />
<beans:property name="authenticationFailureHandler" ref="failureHandler" />
<beans:property name="authenticationSuccessHandler" ref="successHandler" />
</beans:bean>
<http auto-config="false" use-expressions="true"
disable-url-rewriting="true" entry-point-ref="loginUrlAuthenticationEntryPoint">
<csrf disabled="true" />
<custom-filter position="FORM_LOGIN_FILTER"
ref="customUsernamePasswordAuthenticationFilter" />
<custom-filter after="FORM_LOGIN_FILTER" ref="concurrencyFilter" />
<intercept-url pattern="/login" access="permitAll" />
<intercept-url pattern="/" access="permitAll" />
<intercept-url pattern="/api/**" access="hasAnyRole('ROLE_USER')" />
<logout logout-success-url="/login" />
<headers>
<frame-options policy="SAMEORIGIN" />
<hsts include-subdomains="true" disabled="false" />
<header name="Access-Control-Allow-Origin" value="*"/>
<header name="Access-Control-Allow-Methods" value="POST, GET, OPTIONS, DELETE"/>
<header name="Access-Control-Max-Age" value="3600"/>
<header name="Access-Control-Allow-Headers" value="x-requested-with, authorization, Content-Type, *"/>
</headers>
<session-management
session-authentication-strategy-ref="session-management" />
</http>
<beans:bean id="concurrencyFilter"
class="my.app.auth.ConcurrentSessionFilter">
<beans:constructor-arg ref="sessionRegistry" />
<beans:constructor-arg name="expiredUrl" value="/" />
</beans:bean>
<beans:bean id="sessionRegistry" class="my.app.auth.SessionRegistry" />
<beans:bean id="session-management"
class="org.springframework.security.web.authentication.session.CompositeSessionAuthenticationStrategy">
<beans:constructor-arg>
<beans:list>
<beans:bean
class="org.springframework.security.web.authentication.session.ConcurrentSessionControlAuthenticationStrategy">
<beans:constructor-arg ref="sessionRegistry" />
</beans:bean>
<beans:bean
class="org.springframework.security.web.authentication.session.SessionFixationProtectionStrategy" />
<beans:bean
class="org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy">
<beans:constructor-arg ref="sessionRegistry" />
</beans:bean>
</beans:list>
</beans:constructor-arg>
</beans:bean>
<authentication-manager alias="authenticationManager">
<authentication-provider ref="customAuthenticationProvider" />
</authentication-manager>
<beans:bean id="customAuthenticationProvider" class="my.app.auth.UserAuthProvider" />
<beans:bean id="authenticationService" class="my.app.auth.AuthenticationService" />
</beans:beans>
我参考了angular2-spring-boot-security 主题,但我无法解决我的问题,或者我可能还没有理解这个解决方案。
对我的问题有什么建议吗?或者和我商量?谢谢。
【问题讨论】:
显示你的 AngularJS 代码。您是否在第二个请求中添加了JESSIONID
cookie?
@dur:我用 Get 方法请求解决,但 Post 方法请求我有问题,我在下面的答案中发布。
【参考方案1】:
谢谢大家。我通过完全声明Access-Control-Allow-Origin
解决了我的问题。并在配置弹簧中使用withCredentials
,在角度2中使用http
:
<header name="Access-Control-Allow-Origin" value="http://localhost:4200"/>
<header name="withCredentials" value="true"/>
<header name="Access-Control-Allow-Methods" value="GET, POST, OPTIONS, PUT, PATCH, DELETE"/>
<header name="Access-Control-Max-Age" value="3600"/>
<header name="Access-Control-Allow-Headers" value="*"/>
<header name="Access-Control-Allow-Credentials" value="true"/>
并在组件的构造函数中添加http配置:
constructor(private http: Http)
let _build = (<any>http)._backend._browserXHR.build;
(<any>http)._backend._browserXHR.build = () =>
let _xhr = _build();
_xhr.withCredentials = true;
return _xhr;
;
Get 方法请求可以正常工作。但是现在我对 Post 方法请求有很大的问题。当我将 Content-Type 添加到标头中时,请求不要从 cookie 导入 JSESSIONID,但如果我不添加 Content-Type,我将收到有关服务器错误媒体类型的错误代码 415。
我尝试使用角度 2 的 Http
和 XMLHttpRequest
。这里有什么问题?
【讨论】:
以上是关于带有spring-boot安全休息api的角度2的主要内容,如果未能解决你的问题,请参考以下文章
带有 FeignClient 的 Spring Boot RepositoryRestResource
来自 oauth2 安全休息 Web 服务的 Spring 休息服务 api 调用
为啥在发布或更新时重新加载页面以及使用带有 json 服务器的假休息 api 的项目