Angular 有没有办法完全删除spring Security提供的凭据页面,并使用自定义身份验证提供程序实现CSRF?
我试图实现一个基于Spring安全性和Angular 4的CSRF令牌实现。我的应用程序的初始身份验证使用组织的SSO页面。Post,我们将重定向到应用程序主页。下面是我使用两层过滤器实现的WebSecurityConfigureAdapter,一层用于检查和添加CSRF令牌,另一层用于应用程序内部身份验证,目的是使用@Secured提供方法级安全性Angular 有没有办法完全删除spring Security提供的凭据页面,并使用自定义身份验证提供程序实现CSRF?,angular,spring,spring-boot,spring-security,Angular,Spring,Spring Boot,Spring Security,我试图实现一个基于Spring安全性和Angular 4的CSRF令牌实现。我的应用程序的初始身份验证使用组织的SSO页面。Post,我们将重定向到应用程序主页。下面是我使用两层过滤器实现的WebSecurityConfigureAdapter,一层用于检查和添加CSRF令牌,另一层用于应用程序内部身份验证,目的是使用@Secured提供方法级安全性 @Configuration @EnableWebSecurity public class WebSecurityConfiguration e
@Configuration
@EnableWebSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
private static final Logger LOGGER = LoggerFactory.getLogger(WebSecurityConfiguration.class);
@Autowired
private CustomAuthenticationProviderService authenticationProviderService;
public static final String CSRF_COOKIE_NAME = "XSRF-TOKEN";
private static final String[] CSRF_IGNORE = { ""};
private static final String CSRF_HEADER_NAME = "X-XSRF-TOKEN";
@Component
@Order(1)
public class CustomCsrfFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
CsrfToken csrf = (CsrfToken) request.getAttribute(CsrfToken.class.getName());
if (csrf != null) {
Cookie cookie = WebUtils.getCookie(request, CSRF_COOKIE_NAME);
String token = csrf.getToken();
if (cookie == null || token != null && !token.equals(cookie.getValue())) {
cookie = new Cookie(CSRF_COOKIE_NAME, token);
cookie.setPath("/");
cookie.setHttpOnly(false);
response.addCookie(cookie);
}
}
filterChain.doFilter(request, response);
}
}
@Bean
@Order(2)
public FilterRegistrationBean createFilterRegistrationBean() {
FilterRegistrationBean registration = new FilterRegistrationBean(new OncePerRequestFilter() {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
try {
// App method specific authentication code
return;
}
} catch (AuthenticationException e) {
LOGGER.error("Authentication error", e);
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
response.sendRedirect("/error/unauthorized.html");
return;
}
}
@Override
protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException {
String uri = request.getRequestURI();
return uri.startsWith("/resources/") || uri.startsWith("/static/") || uri.startsWith("/css/")
|| uri.startsWith("/images/") || uri.startsWith("/js/") || uri.startsWith("/api/tct/")
|| uri.startsWith("/api/unit/unitConversion");
}
});
return registration;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.httpBasic()
.and().csrf() // csrf config starts here
.ignoringAntMatchers(CSRF_IGNORE) // URI where CSRF check will not be applied
.csrfTokenRepository(csrfTokenRepository()) // defines a repository where tokens are stored
.and().addFilterAfter(new CustomCsrfFilter(), CsrfFilter.class)
; // Csrf filter in
// which we will add
// the cookie
}
private CsrfTokenRepository csrfTokenRepository() {
CookieCsrfTokenRepository tokenRepository = CookieCsrfTokenRepository.withHttpOnlyFalse();
tokenRepository.setCookiePath("/");
return tokenRepository;
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authenticationProviderService);
}
}
以下是我在Angular中嵌入CSRF令牌的代码:
应用程序模块的提供商
{
provide: HTTP_INTERCEPTORS,
useClass: MyHttpInterceptor,
multi: true
}
custom interceptor to append cookies:
import { Injectable } from "@angular/core";
import { tap } from "rxjs/operators";
import {
HttpRequest,
HttpHandler,
HttpEvent,
HttpInterceptor,
HttpResponse,
HttpErrorResponse
} from "@angular/common/http";
import { Observable } from "rxjs/Observable";
@Injectable()
export class MyHttpInterceptor implements HttpInterceptor {
constructor() { }
//function which will be called for all http calls
intercept(
request: HttpRequest<any>,
next: HttpHandler
): Observable<HttpEvent<any>> {
let requestToForward = request;
let token = getCookie("XSRF-TOKEN");
if (token != null) {
requestToForward = request.clone(
{ setHeaders: { 'XSRF-TOKEN': token } });
}
return next.handle(requestToForward);
}
}
function getCookie(name: String) {
const splitCookie = document.cookie.split(';');
for (let i = 0; i < splitCookie.length; i++) {
const splitValue = splitCookie[i].split('=');
if (splitValue[0] === name) {
return splitValue[1];
}
}
return '';
}
{
提供:HTTP_拦截器,
useClass:MyHttpInterceptor,
多:真的
}
用于附加cookie的自定义侦听器:
从“@angular/core”导入{Injectable}”;
从“rxjs/operators”导入{tap};
进口{
HttpRequest,
HttpHandler,
HttpEvent,
HttpInterceptor,
HttpResponse,
HttpErrorResponse
}来自“@angular/common/http”;
从“rxjs/Observable”导入{Observable};
@可注射()
导出类MyHttpInterceptor实现HttpInterceptor{
构造函数(){}
//将为所有http调用调用的函数
拦截(
请求:HttpRequest,
下一步:HttpHandler
):可见{
让requestToForward=请求;
let token=getCookie(“XSRF-token”);
if(令牌!=null){
requestToForward=request.clone(
{setHeaders:{'XSRF-TOKEN':TOKEN}});
}
返回next.handle(requestToForward);
}
}
函数getCookie(名称:String){
const splitCookie=document.cookie.split(“;”);
for(设i=0;i
因此,我得到这个弹出的几个职位要求用户名和密码。由于我已经实现了自定义身份验证,我不依赖于此默认表单上提供的输入进行验证,基本上只需在出现时按“登录”,而不提供任何详细信息。我想删除这个弹出窗口,因为它真的没有任何目的
提前感谢。实现自定义安全性是一种糟糕的做法。@Thomas我不需要整个身份验证/授权部分,但我只需要CSRF实现。我已尝试通过application.yml by security.Basic.enabled禁用http Basic:false,但也无法实现。如果无法禁用它,您正在执行此操作这是错误的。检查官方文件。一切都在这里。@Thomas我相信它更多地与我正在使用的spring security版本相关的自定义实现有关。该项目基于spring Boot 1.7,因此升级到一个较新版本将导致许多功能中断。如果您可以共享一些文档链接,那将非常有用对于同一个版本,我没有任何文档链接,也没有那么旧的东西。祝你好运