spring - 获取请求中的 401 状态
问题描述
大家好,我正在(spring/angular)应用程序中工作,当我发送 GET 请求进行身份验证时,我收到此错误:我将 angular 5 用于前端,将 spring boot 2/mysql 用于后端
这是我的春季安全配置:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter{
@Autowired
private Environment env;
@Autowired
private UserSecurityService userSecurityService;
private BCryptPasswordEncoder passwordEncoder() {
return SecurityUtility.passwordEncoder();
}
private static final String[] PUBLIC_MATCHERS= {
"/css/**",
"/js/**",
"/image/**",
"/book/**",
"/user/**",
};
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.cors().disable().
httpBasic().and().
authorizeRequests().antMatchers(PUBLIC_MATCHERS).permitAll().anyRequest().authenticated();
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userSecurityService).passwordEncoder(passwordEncoder());
}
}
这是我的过滤器:
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class RequestFilter implements Filter{
public void doFilter(ServletRequest req ,ServletResponse res,FilterChain chain) {
HttpServletRequest request = (HttpServletRequest)req;
HttpServletResponse response = (HttpServletResponse)res;
response.setHeader("Access-Control-Allow-Origin","*");
response.setHeader("Access-Control-Allow-Methodes","POST,PUT,GET,OPTIONS,DELETE");
response.setHeader("Access-Control-Allow-Headers","x-requested-with,x-auth-token");
response.setHeader("Access-Control-Allow-Max-Age","3600");
response.setHeader("Access-Control-Allow-Credentials","true");
if(!request.getMethod().equalsIgnoreCase("OPTIONS")){
try {
chain.doFilter(req, res);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
else {
System.out.println("preflight");
response.setHeader("Access-Control-Allow-Methodes","POST,GET,DELETE");
response.setHeader("Access-Control-Allow-Max-Age","3600");
response.setHeader("Access-Control-Allow-Headers","authorization,content-type,x-auth-token,access-control-request-headers,access-control-request-method,accept,origin,x-requested-with");
response.setStatus(HttpServletResponse.SC_OK);
}
}
public void init(FilterConfig filterConfig) {
}
public void destroy() {
}
}
这是我的控制器:
@RequestMapping("/token")
public Map<String, String> token(HttpSession session,HttpServletRequest request){
String remoteHost=request.getRemoteHost();
int portNumber=request.getRemotePort();
System.out.println(remoteHost +":"+portNumber);
System.out.println(request.getRemoteAddr());
return Collections.singletonMap("token",session.getId());
}
这是我的 Angular 5 服务:
@Injectable()
export class LoginService {
constructor(private http: HttpClient) {
}
sendCredential(username: string, password: string) {
let url = "http://localhost:8080/token";
let encodedCredentials = btoa(username + ':' + password);
let basicHeader = "Basic " + encodedCredentials;
let headers=new HttpHeaders({
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': basicHeader
});
return this.http.get(url,{headers:headers});
}
}
解决方案
请允许来自您的安全配置类的 OPTIONS 请求,因为客户端(角度)首先发送 OPTIONS 请求以验证服务器是否允许自定义添加的标头,然后将实际请求发送到服务器。
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.cors().disable()
.authorizeRequests()
.antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
.antMatchers(PUBLIC_MATCHERS).permitAll()
.anyRequest().authenticated()
.and()
.httpBasic();
}
注意:请注意,因为您使用的是Bcrypt
密码,但Basic Http
会发送Base64
编码密码,因此这可能会出现问题,因此请检查UserSecurityService
.
推荐阅读
- coq - 我想对 Peano nats 进行归纳,但我想证明一个属性 P 超过 nats 1 ... n。Coq 是否提供了一种策略/工具来做到这一点?
- c - 如何调试使用 gdb 中辅助 txt 文件输入的程序?
- php - View Composer 在我的 Laravel 应用程序中不起作用
- javascript - 更新全局变量的值
- javascript - v-for 转 JSON 复合体
- html - CSS更改图像以在缩放时堆叠
- javascript - 通过 React 的 useState 钩子设置状态时删除键的最佳或最有效的方法是什么?
- r - 如何使用 R 中的百分位数为两种类型的样本制作箱线图
- google-app-engine - .net 核心通用主机在部署到谷歌云应用引擎时运行两次
- python - 如何使用 Ta-lib 或 Pandas 正确计算股票的 EMA?