Angular 401在具有不同端口的API上未经授权
我有一个由JHipster生成的项目。后端为弹簧,前端为角形。我使用Azure b2c,比如IDP oauth2 项目中有不同的Web服务设置在不同的端口上(端口8080上的/api/account,端口8082上的/api/get_template) 签到/签到流程正常工作;我可以登录,b2c在重定向Uri上返回我,我可以调用/api/account上定义的服务,它给我响应状态200 当我尝试在api/get_模板上执行get调用时,服务器会给我未经授权的状态。我所做的唯一一件事就是这样设置代理配置:对于context“/api/account”,目标设置为“localhost:8080”,而对于context“/api/get_template”,目标设置为“localhost:8082” 我不知道我能做什么…有什么建议吗 这是我的proxy.config.jsonAngular 401在具有不同端口的API上未经授权,angular,spring,web-services,jhipster,azure-ad-b2c,Angular,Spring,Web Services,Jhipster,Azure Ad B2c,我有一个由JHipster生成的项目。后端为弹簧,前端为角形。我使用Azure b2c,比如IDP oauth2 项目中有不同的Web服务设置在不同的端口上(端口8080上的/api/account,端口8082上的/api/get_template) 签到/签到流程正常工作;我可以登录,b2c在重定向Uri上返回我,我可以调用/api/account上定义的服务,它给我响应状态200 当我尝试在api/get_模板上执行get调用时,服务器会给我未经授权的状态。我所做的唯一一件事就是这样设置代
const PROXY_CONFIG = [
{
context: [
'/api/account',
'/services',
'/management',
'/swagger-resources',
'/v2/api-docs',
'/h2-console',
'/oauth2',
'/login',
'/auth'
],
target: "http://localhost:8080",
secure: false,
loglevel: "debug",
changeOrigin: false
},
{
context: [
'/api/get_template'
],
target: "http://localhost:8084",
secure: false,
loglevel: "debug",
changeOrigin: false
}
]
module.exports = PROXY_CONFIG;
这是我对文件夹微服务的安全配置
package it.test.webservices.config;
import io.github.jhipster.config.JHipsterProperties;
import it.test.webservices.security.SecurityUtils;
import it.test.webservices.security.oauth2.JwtGrantedAuthorityConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;
import org.springframework.core.convert.converter.Converter;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.configurers.oauth2.server.resource.OAuth2ResourceServerConfigurer;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper;
import org.springframework.security.oauth2.core.oidc.user.OidcUserAuthority;
import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter;
import org.springframework.security.web.csrf.CookieCsrfTokenRepository;
import org.springframework.security.web.csrf.CsrfFilter;
import org.springframework.security.web.header.writers.ReferrerPolicyHeaderWriter;
import org.springframework.web.filter.CorsFilter;
import org.zalando.problem.spring.web.advice.security.SecurityProblemSupport;
import java.util.HashSet;
import java.util.Set;
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
@Import(SecurityProblemSupport.class)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
private final CorsFilter corsFilter;
/*@Value("${spring.security.oauth2.client.provider.oidc.issuer-uri}")
private String issuerUri;*/
private final JHipsterProperties jHipsterProperties;
private final SecurityProblemSupport problemSupport;
public SecurityConfiguration(CorsFilter corsFilter, JHipsterProperties jHipsterProperties, SecurityProblemSupport problemSupport) {
this.corsFilter = corsFilter;
this.problemSupport = problemSupport;
this.jHipsterProperties = jHipsterProperties;
}
@Override
public void configure(WebSecurity web) {
web.ignoring()
.antMatchers(HttpMethod.OPTIONS, "/**")
.antMatchers("/swagger-ui/index.html")
.antMatchers("/test/**");
}
/* @Override
public void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.and()
.addFilterBefore(corsFilter, CsrfFilter.class)
.exceptionHandling()
.authenticationEntryPoint(problemSupport)
.accessDeniedHandler(problemSupport)
.and()
.headers()
.contentSecurityPolicy("default-src 'self'; frame-src 'self' data:; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://storage.googleapis.com; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self' data:")
.and()
.referrerPolicy(ReferrerPolicyHeaderWriter.ReferrerPolicy.STRICT_ORIGIN_WHEN_CROSS_ORIGIN)
.and()
.featurePolicy("geolocation 'none'; midi 'none'; sync-xhr 'none'; microphone 'none'; camera 'none'; magnetometer 'none'; gyroscope 'none'; speaker 'none'; fullscreen 'self'; payment 'none'")
.and()
.frameOptions()
.deny()
.and()
.authorizeRequests()
.antMatchers("/api/auth-info").permitAll()
.antMatchers("/api/**").authenticated()
.antMatchers("/websocket/tracker").hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/websocket/**").permitAll()
.antMatchers("/management/health").permitAll()
.antMatchers("/management/info").permitAll()
.antMatchers("/management/prometheus").permitAll()
.antMatchers("/management/**").hasAuthority(AuthoritiesConstants.ADMIN)
.and()
.oauth2Login()
.and()
.oauth2ResourceServer()
.jwt()
.jwtAuthenticationConverter(authenticationConverter())
.and()
.and()
.oauth2Client();
// @formatter:on
}*/
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.and()
.addFilterBefore(corsFilter, CsrfFilter.class)
.exceptionHandling()
.authenticationEntryPoint(problemSupport)
.accessDeniedHandler(problemSupport)
.and()
.headers()
.contentSecurityPolicy("default-src 'self'; frame-src 'self' data:; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://storage.googleapis.com; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self' data:")
.and()
.referrerPolicy(ReferrerPolicyHeaderWriter.ReferrerPolicy.STRICT_ORIGIN_WHEN_CROSS_ORIGIN)
.and()
.featurePolicy("geolocation 'none'; midi 'none'; sync-xhr 'none'; microphone 'none'; camera 'none'; magnetometer 'none'; gyroscope 'none'; speaker 'none'; fullscreen 'self'; payment 'none'")
.and()
.frameOptions()
.deny()
.and()
.authorizeRequests()
.antMatchers("/api/**") .hasAuthority("SCOPE_Api.Read")
.anyRequest()
.authenticated()
.and()
.oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt);
// .oauth2ResourceServer()
// .jwt()
// .jwtAuthenticationConverter(authenticationConverter());
}
Converter<Jwt, AbstractAuthenticationToken> authenticationConverter() {
JwtAuthenticationConverter jwtAuthenticationConverter = new JwtAuthenticationConverter();
jwtAuthenticationConverter.setJwtGrantedAuthoritiesConverter(new JwtGrantedAuthorityConverter());
return jwtAuthenticationConverter;
}
/**
* Map authorities from "groups" or "roles" claim in ID Token.
*
* @return a {@link GrantedAuthoritiesMapper} that maps groups from
* the IdP to Spring Security Authorities.
*/
@Bean
public GrantedAuthoritiesMapper userAuthoritiesMapper() {
return (authorities) -> {
Set<GrantedAuthority> mappedAuthorities = new HashSet<>();
authorities.forEach(authority -> {
// Check for OidcUserAuthority because Spring Security 5.2 returns
// each scope as a GrantedAuthority, which we don't care about.
if (authority instanceof OidcUserAuthority) {
OidcUserAuthority oidcUserAuthority = (OidcUserAuthority) authority;
mappedAuthorities.addAll(SecurityUtils.extractAuthorityFromClaims(oidcUserAuthority.getUserInfo().getClaims()));
}
});
return mappedAuthorities;
};
}
/*
@Bean
JwtDecoder jwtDecoder() {
NimbusJwtDecoder jwtDecoder = (NimbusJwtDecoder) JwtDecoders.fromOidcIssuerLocation(issuerUri);
OAuth2TokenValidator<Jwt> audienceValidator = new AudienceValidator(jHipsterProperties.getSecurity().getOauth2().getAudience());
OAuth2TokenValidator<Jwt> withIssuer = JwtValidators.createDefaultWithIssuer(issuerUri);
OAuth2TokenValidator<Jwt> withAudience = new DelegatingOAuth2TokenValidator<>(withIssuer, audienceValidator);
jwtDecoder.setJwtValidator(withAudience);
return jwtDecoder;
}
*/
}
package it.test.webservices.config;
导入io.github.jhipster.config.JHipsterProperties;
导入it.test.webservices.security.SecurityUtils;
导入it.test.webservices.security.oauth2.JwtGrantedAuthorityConverter;
导入org.springframework.context.annotation.Bean;
导入org.springframework.context.annotation.import;
导入org.springframework.core.convert.converter.converter;
导入org.springframework.http.HttpMethod;
导入org.springframework.security.authentication.AbstractAuthenticationToken;
导入org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
导入org.springframework.security.config.annotation.web.builders.HttpSecurity;
导入org.springframework.security.config.annotation.web.builders.WebSecurity;
导入org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
导入org.springframework.security.config.annotation.web.configuration.websecurityConfigureAdapter;
导入org.springframework.security.config.annotation.web.configurers.oauth2.server.resource.OAuth2ResourceServerConfigurer;
导入org.springframework.security.core.GrantedAuthority;
导入org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper;
导入org.springframework.security.oauth2.core.oidc.user.OidcUserAuthority;
导入org.springframework.security.oauth2.jwt.jwt;
导入org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter;
导入org.springframework.security.web.csrf.CookieCsrfTokenRepository;
导入org.springframework.security.web.csrf.CsrfFilter;
导入org.springframework.security.web.header.writers.refererPolicyHeaderWriter;
导入org.springframework.web.filter.CorsFilter;
导入org.zalando.problem.spring.web.advice.security.SecurityProblemSupport;
导入java.util.HashSet;
导入java.util.Set;
@启用Web安全性
@EnableGlobalMethodSecurity(Prespenabled=true,securedEnabled=true)
@导入(SecurityProblemSupport.class)
公共类安全配置扩展了WebSecurity配置适配器{
私人最终公司过滤器;
/*@值(${spring.security.oauth2.client.provider.oidc.issuer uri}”)
私有字符串issuerUri*/
私人最终产权;
私人最终证券问题支持问题支持;
公共安全配置(公司过滤器、JHIPSterprities JHIPSterprities、安全问题支持问题支持){
this.corsFilter=corsFilter;
this.problemSupport=problemSupport;
this.jhipsterpreproperties=jhipsterpreproperties;
}
@凌驾
公共void配置(WebSecurity web){
忽略
.antMatchers(HttpMethod.OPTIONS,“/**”)
.antMatchers(“/swagger ui/index.html”)
.antMatchers(“/test/**”);
}
/*@覆盖
public void configure(HttpSecurity http)引发异常{
//@formatter:off
http
.csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.WithTpOnlyFalse())
.及()
.addFilterBefore(corsFilter,CsrfFilter.class)
.例外处理()
.authenticationEntryPoint(问题支持)
.accessDeniedHandler(问题支持)
.及()
.headers()
.contentSecurityPolicy(“默认src'self';框架src'self'数据:;脚本src'self'”不安全内联“不安全评估”https://storage.googleapis.com;样式src'self'unsafe inline';img src'self'数据:;字体src'self'数据:)
.及()
.referrerPolicy(ReferrerPolicyHeaderWriter.referrerPolicy.STRICT_ORIGIN_交叉_ORIGIN_时)
.及()
.featurePolicy(“地理定位‘无’;midi‘无’;同步xhr‘无’;麦克风‘无’;相机‘无’;磁强计‘无’;陀螺仪‘无’;扬声器‘无’;全屏‘自我’;付款‘无’)
.及()
.frameOptions()
.deny()
.及()
.授权请求()
.antMatchers(“/api/auth info”).permitAll()