Bu biraz eski olduğunu biliyorum ama sadece bu çok sorunu çözmek zorunda kaldı ve gerçekten yeni desteler halinde bir şey bulamadı.
Aynı CAS hizmetini paylaşan birden fazla ortama sahibiz (think dev, qa, uat ve local development environment); Her ortama birden fazla URL'den (istemci tarafındaki web sunucusu üzerinden bir ters proxy üzerinden ve doğrudan arka uç sunucusuna) vurma yeteneğine sahibiz. Bu, tek bir URL'yi belirtmenin en iyi ihtimalle zor olduğu anlamına gelir. Belki de bunu yapmanın bir yolu var ama bir dinamik ServiceProperties.getService()
'u kullanabiliyorum. URL'nin bir noktada ele geçirilmediğinden emin olmak için büyük olasılıkla bir çeşit sunucu sonek denetimi ekleyeceğim.
İşte
- geçersiz kılma
CasAuthenticationFilter
... Ben ne olursa olsun güvenli kaynağa erişmek için kullanılan URL çalışan temel CAS akışını almak için bunu yaptık.
CasAuthenticationProvider
'u geçersiz kılın. ServiceProperties
numaralı telefondan
setAuthenticateAllArtifacts(true)
. @Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, jsr250Enabled = true)
public class CasSecurityConfiguration extends WebSecurityConfigurerAdapter {
Sadece her zamanki bahar yapılandırma fasulye:
İşte benim bahar yapılandırma fasulye uzun formudur.
@Value("${cas.server.url:https://localhost:9443/cas}")
private String casServerUrl;
@Value("${cas.service.validation.uri:/webapi/j_spring_cas_security_check}")
private String casValidationUri;
@Value("${cas.provider.key:whatever_your_key}")
private String casProviderKey;
Bazı harici yapılandırma parametreleri.
@Bean
public ServiceProperties serviceProperties() {
ServiceProperties serviceProperties = new ServiceProperties();
serviceProperties.setService(casValidationUri);
serviceProperties.setSendRenew(false);
serviceProperties.setAuthenticateAllArtifacts(true);
return serviceProperties;
}
önemli şey yukarıda setAuthenticateAllArtifacts(true)
çağrıdır. Bu mevcut bir UserDetailsService
@Bean
public CasAuthenticationProvider casAuthenticationProvider() {
CasAuthenticationProvider casAuthenticationProvider = new CasAuthenticationProvider();
casAuthenticationProvider.setAuthenticationUserDetailsService(authenticationUserDetailsService());
casAuthenticationProvider.setServiceProperties(serviceProperties());
casAuthenticationProvider.setTicketValidator(cas20ServiceTicketValidator());
casAuthenticationProvider.setKey(casProviderKey);
return casAuthenticationProvider;
}
için .. servis bilet doğrulayıcı kodlanmış
ServiceProperties.getService()
çağrı
@Bean
public Cas20ServiceTicketValidator cas20ServiceTicketValidator() {
return new Cas20ServiceTicketValidator(casServerUrl);
}
Standart bilet doğrulayıcı yerine AuthenticationDetailsSource
uygulamayı kullanacaktır
@Resource
private UserDetailsService userDetailsService;
@Bean
public AuthenticationUserDetailsService authenticationUserDetailsService() {
return new AuthenticationUserDetailsService() {
@Override
public UserDetails loadUserDetails(Authentication token) throws UsernameNotFoundException {
String username = (token.getPrincipal() == null) ? "NONE_PROVIDED" : token.getName();
return userDetailsService.loadUserByUsername(username);
}
};
}
Standart kanca yapacak
Standart kimlik doğrulama sağlayıcısı
Burada
@Bean
public CasAuthenticationFilter casAuthenticationFilter() throws Exception {
CasAuthenticationFilter casAuthenticationFilter = new CasAuthenticationFilter();
casAuthenticationFilter.setAuthenticationManager(authenticationManager());
casAuthenticationFilter.setServiceProperties(serviceProperties());
casAuthenticationFilter.setAuthenticationDetailsSource(dynamicServiceResolver());
return casAuthenticationFilter;
}
Anahtar dynamicServiceResolver()
ayarı ..
@Bean
AuthenticationDetailsSource<HttpServletRequest,
ServiceAuthenticationDetails> dynamicServiceResolver() {
return new AuthenticationDetailsSource<HttpServletRequest, ServiceAuthenticationDetails>() {
@Override
public ServiceAuthenticationDetails buildDetails(HttpServletRequest context) {
final String url = makeDynamicUrlFromRequest(serviceProperties());
return new ServiceAuthenticationDetails() {
@Override
public String getServiceUrl() {
return url;
}
};
}
};
}
Dinamik
makeDynamicUrlFromRequest()
yönteminden hizmet url yaratmasıdır. Bu bit bilet doğrulaması üzerine kullanılır.
@Bean
public CasAuthenticationEntryPoint casAuthenticationEntryPoint() {
CasAuthenticationEntryPoint casAuthenticationEntryPoint = new CasAuthenticationEntryPoint() {
@Override
protected String createServiceUrl(final HttpServletRequest request, final HttpServletResponse response) {
return CommonUtils.constructServiceUrl(null, response, makeDynamicUrlFromRequest(serviceProperties())
, null, serviceProperties().getArtifactParameter(), false);
}
};
casAuthenticationEntryPoint.setLoginUrl(casServerUrl + "/login");
casAuthenticationEntryPoint.setServiceProperties(serviceProperties());
return casAuthenticationEntryPoint;
}
CAS, giriş ekranına yeniden yönlendirmek istediğinde, bu bölüm aynı dinamik URL oluşturucuyu kullanır.
private String makeDynamicUrlFromRequest(ServiceProperties serviceProperties){
return "https://howeverYouBuildYourOwnDynamicUrl.com";
}
Bu, ne yaparsanız yapın. Yalnızca yapılandırdığımız hizmetin URI'sini tutmak için ServiceProperties uygulamasından geçtim. Biz arka tarafında HATEAOS kullanmak ve benzeri bir uygulama vardır:
return UriComponentsBuilder.fromHttpUrl(
linkTo(methodOn(ExposedRestResource.class)
.aMethodOnThatResource(null)).withSelfRel().getHref())
.replacePath(serviceProperties.getService())
.build(false)
.toUriString();
Düzenleme: Burada ben geçerli sunucu soneklerinin listesi için yaptık ..
private List<String> validCasServerHostEndings;
@Value("${cas.valid.server.suffixes:company.com,localhost}")
private void setValidCasServerHostEndings(String endings){
validCasServerHostEndings = new ArrayList<>();
for (String ending : StringUtils.split(endings, ",")) {
if (StringUtils.isNotBlank(ending)){
validCasServerHostEndings.add(StringUtils.trim(ending));
}
}
}
private String makeDynamicUrlFromRequest(ServiceProperties serviceProperties){
UriComponents url = UriComponentsBuilder.fromHttpUrl(
linkTo(methodOn(ExposedRestResource.class)
.aMethodOnThatResource(null)).withSelfRel().getHref())
.replacePath(serviceProperties.getService())
.build(false);
boolean valid = false;
for (String validCasServerHostEnding : validCasServerHostEndings) {
if (url.getHost().endsWith(validCasServerHostEnding)){
valid = true;
break;
}
}
if (!valid){
throw new AccessDeniedException("The server is unable to authenticate the requested url.");
}
return url.toString();
}
Yay 3 kullanıyorum; bahar güvenliği 3 docs –
bağlantıya dikkat edin Belki de [bu bağlantı] (https://jira.springsource.org/browse/SEC-1374) sizin gereksiniminiz/probleminizle ilgili bazı bilgiler veriyor? – Raghuram
Evet, kesinlikle bir şey öğrendim ve olası bir çözümü yok ettim. HTTP isteğine güvenemediğimden, hizmetin güvenli olması gereken dağıtım zamanında bazı türetilmiş değerler aracılığıyla ayarlanmasını istiyorum. –