程序问答   发布时间:2022-06-01  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了在 Spring Security 中将 Azure AD 配置为 IDP大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

如何解决在 Spring Security 中将 Azure AD 配置为 IDP?

开发过程中遇到在 Spring Security 中将 Azure AD 配置为 IDP的问题如何解决?下面主要结合日常开发的经验,给出你关于在 Spring Security 中将 Azure AD 配置为 IDP的解决方法建议,希望对你解决在 Spring Security 中将 Azure AD 配置为 IDP有所启发或帮助;

所以我尝试将 Azure AD 用作 SAML IDP,但在运行时我不断收到以下错误:@H_874_3@

2021-02-05 16:09:16.303 ERROR 3760 --- [nio-8080-exec-9] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [org.opensaml.saml2.Metadata.provIDer.MetadataProvIDerException: No IDP was configured,please update included Metadata with at least one IDP] with root cause

org.opensaml.saml2.Metadata.provIDer.MetadataProvIDerException: No IDP was configured,please update included Metadata with at least one IDP
    at org.springframework.security.saml.Metadata.MetadataManager.getDefaultIDP(MetadataManager.java:795) ~[spring-security-saml2-core-1.0.2.RELEASE.jar:1.0.2.RELEASE]
    at org.springframework.security.saml.context.SAMLContextProvIDerImpl.populatePeerEntityID(SAMLContextProvIDerImpl.java:157) ~[spring-security-saml2-core-1.0.2.RELEASE.jar:1.0.2.RELEASE]
    at org.springframework.security.saml.context.SAMLContextProvIDerImpl.getLocalAndPeerEntity(SAMLContextProvIDerImpl.java:127) ~[spring-security-saml2-core-1.0.2.RELEASE.jar:1.0.2.RELEASE]
    at org.springframework.security.saml.SAMLEntryPoint.commence(SAMLEntryPoint.java:146) ~[spring-security-saml2-core-1.0.2.RELEASE.jar:1.0.2.RELEASE]
    at org.springframework.security.web.access.ExceptionTranslationFilter.sendStartAuthentication(ExceptionTranslationFilter.java:203) ~[spring-security-web-4.2.2.RELEASE.jar:4.2.2.RELEASE]
    at org.springframework.security.web.access.ExceptionTranslationFilter.handleSpringSecurityException(ExceptionTranslationFilter.java:177) ~[spring-security-web-4.2.2.RELEASE.jar:4.2.2.RELEASE]
    at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:133) ~[spring-security-web-4.2.2.RELEASE.jar:4.2.2.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.2.2.RELEASE.jar:4.2.2.RELEASE]
    at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137) ~[spring-security-web-4.2.2.RELEASE.jar:4.2.2.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.2.2.RELEASE.jar:4.2.2.RELEASE]
    at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111) ~[spring-security-web-4.2.2.RELEASE.jar:4.2.2.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.2.2.RELEASE.jar:4.2.2.RELEASE]
    at org.springframework.security.web.servletAPI.SecurityContextHolderAwarerequestFilter.doFilter(SecurityContextHolderAwarerequestFilter.java:170) ~[spring-security-web-4.2.2.RELEASE.jar:4.2.2.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.2.2.RELEASE.jar:4.2.2.RELEASE]
    at org.springframework.security.web.savedrequest.requestCacheAwareFilter.doFilter(requestCacheAwareFilter.java:63) ~[spring-security-web-4.2.2.RELEASE.jar:4.2.2.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.2.2.RELEASE.jar:4.2.2.RELEASE]
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:208) ~[spring-security-web-4.2.2.RELEASE.jar:4.2.2.RELEASE]
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:185) ~[spring-security-web-4.2.2.RELEASE.jar:4.2.2.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.2.2.RELEASE.jar:4.2.2.RELEASE]
    at org.springframework.security.web.authentication.logout.logoutFilter.doFilter(logoutFilter.java:116) ~[spring-security-web-4.2.2.RELEASE.jar:4.2.2.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.2.2.RELEASE.jar:4.2.2.RELEASE]
    at org.springframework.security.web.header.headerWriterFilter.doFilterInternal(headerWriterFilter.java:64) ~[spring-security-web-4.2.2.RELEASE.jar:4.2.2.RELEASE]
    at org.springframework.web.filter.oncePerrequestFilter.doFilter(OncePerrequestFilter.java:107) ~[spring-web-4.3.8.RELEASE.jar:4.3.8.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.2.2.RELEASE.jar:4.2.2.RELEASE]
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105) ~[spring-security-web-4.2.2.RELEASE.jar:4.2.2.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.2.2.RELEASE.jar:4.2.2.RELEASE]
    at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56) ~[spring-security-web-4.2.2.RELEASE.jar:4.2.2.RELEASE]
    at org.springframework.web.filter.oncePerrequestFilter.doFilter(OncePerrequestFilter.java:107) ~[spring-web-4.3.8.RELEASE.jar:4.3.8.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.2.2.RELEASE.jar:4.2.2.RELEASE]
    at org.springframework.security.saml.Metadata.MetadataGeneratorFilter.doFilter(MetadataGeneratorFilter.java:87) ~[spring-security-saml2-core-1.0.2.RELEASE.jar:1.0.2.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.2.2.RELEASE.jar:4.2.2.RELEASE]
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:214) ~[spring-security-web-4.2.2.RELEASE.jar:4.2.2.RELEASE]
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:177) ~[spring-security-web-4.2.2.RELEASE.jar:4.2.2.RELEASE]
    at org.springframework.web.filter.DelegaTingFilterProxy.invokeDelegate(DelegaTingFilterProxy.java:346) ~[spring-web-4.3.8.RELEASE.jar:4.3.8.RELEASE]
    at org.springframework.web.filter.DelegaTingFilterProxy.doFilter(DelegaTingFilterProxy.java:262) ~[spring-web-4.3.8.RELEASE.jar:4.3.8.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.14.jar:8.5.14]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.14.jar:8.5.14]
    at org.springframework.web.filter.requestContextFilter.doFilterInternal(requestContextFilter.java:99) ~[spring-web-4.3.8.RELEASE.jar:4.3.8.RELEASE]
    at org.springframework.web.filter.oncePerrequestFilter.doFilter(OncePerrequestFilter.java:107) ~[spring-web-4.3.8.RELEASE.jar:4.3.8.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.14.jar:8.5.14]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.14.jar:8.5.14]
    at org.springframework.web.filter.httpPutFormContentFilter.doFilterInternal(httpPutFormContentFilter.java:105) ~[spring-web-4.3.8.RELEASE.jar:4.3.8.RELEASE]
    at org.springframework.web.filter.oncePerrequestFilter.doFilter(OncePerrequestFilter.java:107) ~[spring-web-4.3.8.RELEASE.jar:4.3.8.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.14.jar:8.5.14]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.14.jar:8.5.14]
    at org.springframework.web.filter.HIDdenhttpR_2_11845@ethodFilter.doFilterInternal(HIDdenhttpR_2_11845@ethodFilter.java:81) ~[spring-web-4.3.8.RELEASE.jar:4.3.8.RELEASE]
    at org.springframework.web.filter.oncePerrequestFilter.doFilter(OncePerrequestFilter.java:107) ~[spring-web-4.3.8.RELEASE.jar:4.3.8.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.14.jar:8.5.14]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.14.jar:8.5.14]
    at org.springframework.web.filter.CharacterEnCodingFilter.doFilterInternal(CharacterEnCodingFilter.java:197) ~[spring-web-4.3.8.RELEASE.jar:4.3.8.RELEASE]
    at org.springframework.web.filter.oncePerrequestFilter.doFilter(OncePerrequestFilter.java:107) ~[spring-web-4.3.8.RELEASE.jar:4.3.8.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.14.jar:8.5.14]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.14.jar:8.5.14]
    at org.apache.catalina.core.StandarDWrapperValve.invoke(StandarDWrapperValve.java:198) ~[tomcat-embed-core-8.5.14.jar:8.5.14]
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-8.5.14.jar:8.5.14]
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478) [tomcat-embed-core-8.5.14.jar:8.5.14]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) [tomcat-embed-core-8.5.14.jar:8.5.14]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80) [tomcat-embed-core-8.5.14.jar:8.5.14]
    at org.apache.catalina.core.StandardENGIneValve.invoke(StandardENGIneValve.java:87) [tomcat-embed-core-8.5.14.jar:8.5.14]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342) [tomcat-embed-core-8.5.14.jar:8.5.14]
    at org.apache.coyote.http11.http11Processor.service(http11Processor.java:799) [tomcat-embed-core-8.5.14.jar:8.5.14]
    at org.apache.coyote.AbstractProcessorlight.process(AbstractProcessorlight.java:66) [tomcat-embed-core-8.5.14.jar:8.5.14]
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:861) [tomcat-embed-core-8.5.14.jar:8.5.14]
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1455) [tomcat-embed-core-8.5.14.jar:8.5.14]
    at org.apache.tomcat.util.net.socketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.14.jar:8.5.14]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_271]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_271]
    at org.apache.tomcat.util.threads.TaskThread$WrapPingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.14.jar:8.5.14]
    at java.lang.Thread.run(Thread.java:748) [na:1.8.0_271]

2021-02-05 16:09:18.804  INFO 3760 --- [Metadata-reload] .s.m.p.AbstractReloadingMetadataProvIDer : Next refresh cycle for Metadata provIDer 'file:/C:/Projects/New%20folder/saml-jwt-sample/target/classes/rtw-saml-app-1.xml' will occur on '2021-02-05T15:14:18.804Z' ('2021-02-05T16:14:18.804+01:00' local timE)
2021-02-05 16:09:18.804 ERROR 3760 --- [Metadata-reload] o.o.s.m.p.AbstractMetadataProvIDer       : Metadata provIDer Failed to properly initialize,fail-fast=true,halTing

org.opensaml.saml2.Metadata.provIDer.MetadataProvIDerException: java.lang.NullPointerException
    at org.opensaml.saml2.Metadata.provIDer.AbstractReloadingMetadataProvIDer.refresh(AbstractReloadingMetadataProvIDer.java:267) ~[opensaml-2.6.1.jar:na]
    at org.opensaml.saml2.Metadata.provIDer.AbstractReloadingMetadataProvIDer.doInitialization(AbstractReloadingMetadataProvIDer.java:236) ~[opensaml-2.6.1.jar:na]
    at org.opensaml.saml2.Metadata.provIDer.AbstractMetadataProvIDer.initialize(AbstractMetadataProvIDer.java:407) ~[opensaml-2.6.1.jar:na]
    at org.springframework.security.saml.Metadata.ExtendedMetadataDelegate.initialize(ExtendedMetadataDelegate.java:167) [spring-security-saml2-core-1.0.2.RELEASE.jar:1.0.2.RELEASE]
    at org.springframework.security.saml.Metadata.MetadataManager.initializeProvIDer(MetadataManager.java:412) [spring-security-saml2-core-1.0.2.RELEASE.jar:1.0.2.RELEASE]
    at org.springframework.security.saml.Metadata.MetadataManager.refreshMetadata(MetadataManager.java:238) [spring-security-saml2-core-1.0.2.RELEASE.jar:1.0.2.RELEASE]
    at org.springframework.security.saml.Metadata.CachingMetadataManager.refreshMetadata(CachingMetadataManager.java:86) [spring-security-saml2-core-1.0.2.RELEASE.jar:1.0.2.RELEASE]
    at org.springframework.security.saml.Metadata.MetadataManager$refreshTask.run(MetadataManager.java:1040) [spring-security-saml2-core-1.0.2.RELEASE.jar:1.0.2.RELEASE]
    at java.util.TimerThread.mainLoop(Timer.java:555) [na:1.8.0_271]
    at java.util.TimerThread.run(Timer.java:505) [na:1.8.0_271]
Caused by: java.lang.NullPointerException: null
    at org.opensaml.saml2.common.SAML2Helper.getEarlIEstExpiration(SAML2Helper.java:112) ~[opensaml-2.6.1.jar:na]
    at org.opensaml.saml2.Metadata.provIDer.AbstractReloadingMetadataProvIDer.processCachedMetadata(AbstractReloadingMetadataProvIDer.java:328) ~[opensaml-2.6.1.jar:na]
    at org.opensaml.saml2.Metadata.provIDer.AbstractReloadingMetadataProvIDer.refresh(AbstractReloadingMetadataProvIDer.java:258) ~[opensaml-2.6.1.jar:na]
    ... 9 common frames omitted

我正在使用 https://www.sylvainlemoine.com/2016/06/06/spring-saml2.0-websso-and-jwt-for-mobile-api/ 所述的 SAML 解决方案,并怀疑问题可能是我对这些 bean 使用了错误的信息。 :@H_874_3@

    @Bean
    public MetadataGenerator MetadataGenerator() {
        MetadataGenerator MetadataGenerator = new MetadataGenerator();
        MetadataGenerator.setEntityID("SamlJwtSampleEntityID");
        MetadataGenerator.setExtendedMetadata(extendedMetadata());
        MetadataGenerator.seTincludediscoveryExtension(false);
        MetadataGenerator.setKeymanager(keymanager());
        return MetadataGenerator;
    }

    @Bean
    public Keymanager keymanager() {
        ClassPathresource storefile = new ClassPathresource("/saml-keystore.jks");
        String storePass = "samlstorepass";
        Map<String,String> passwords = new HashMap<>();
        passwords.put("mykeyalias","mykeypass");
        return new JKSKeymanager(storefile,storePass,passwords,"mykeyalias");
    }

我根据使用以下内容从 Azure 门户下载的元数据文件和证书文件创建了一个新的 jks 文件:@H_874_3@

keytool -importcert -genkeypair -alias saml-app-1 -keypass keypass -storepass samlstorepass -keystore saml-app-1.jks -file saml-app-1.cer@H_874_3@

并更新了上面代码中的密码和文件名。@H_874_3@

有什么指点吗?@H_874_3@

解决方法

如果您尝试使用 springboot 向 Java Web 应用程序添加身份验证,我认为此 document 可以帮助您,它提供了一个关于集成 azure 广告的示例。@H_874_3@

如果你想把springboot后端应用做成一个API应用(前后端分离),我有个想法,你可以用masl.js在前端应用中实现登录模块,后端应用程序只是添加过滤器来检查请求是否被同意。我曾经写过一个像下面这样的过滤器。@H_874_3@

package com.example.demo;

import java.io.IOException;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.Servletrequest;
import javax.servlet.ServletResponse;
import javax.servlet.Annotation.WebFilter;
import javax.servlet.http.httpServletrequest;
import javax.servlet.http.httpServletResponse;
import com.alibaba.fastjson.JSONObject;
import com.auth0.jwt.JWT;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;

//@Component
@WebFilter(filterName = "AdHelloFilter",urlPatterns = {"/ad/*"})
public class AdHelloFilter implements Filter  {

    @Override
    public void doFilter(Servletrequest request,ServletResponse response,FilterChain filterChain)
            throws IOException,ServletException {
        
        httpServletrequest httprequest = (httpServletrequest) request;
        httpServletResponse httpResponse= (httpServletResponsE) response;
        
        final String requestTokenHeader = httprequest.getHeader("Authorization");
        if (requestTokenHeader != null && requestTokenHeader.startsWith("Bearer ")) {
            String jwtToken = requestTokenHeader.subString(7);
            try {
                DecodedJWT jwt = JWT.decode(jwtToken);
                //judge if expired
                Date expiresAt = jwt.getExpiresAt();
                if(expiresAt.before(new Date())) {
                    Map<String,Object> errRes = new HashMap<String,Object>();
                    Map<String,Object> errMesg = new HashMap<String,Object>();
                    errMesg.put("code","InvalidAuthenticationToken");
                    errMesg.put("message","Access token has expired.");
                    errRes.put("error",errMesg);
                    String json = JSONObject.toJSONString(errRes);   
                    httpResponse.sendError(httpServletResponse.SC_UNAUTHORIZED,json);
                    return;
                }
                //judge if has specific scope
                Claim a = jwt.getClaim("scp");
                String scope = a.asString();
                String[] scopeArr = scope.split(" ");
                List<String> scopeList= Arrays.asList(scopeArr);
                if(!(scopeList.contains("User.Read") && scopeList.contains("Mail.Read"))) {
                    Map<String,"Unauthorized,pls add api permission");
                    errRes.put("error",errMesg);
                    String json = JSONObject.toJSONString(errRes);   
                    httpResponse.sendError(httpServletResponse.SC_FORBIDDEN,json);
                    return;
                }
            } catch (JWTDecodeException exception){
                System.out.println("Unable to Decode the JWT Token");
            }
        } else {
            httpResponse.sendError(httpServletResponse.SC_UNAUTHORIZED);
            return;
        }
        filterChain.doFilter(request,responsE);
    }
    
    @Override
    public void init (FilterConfig filterConfig) throws ServletException{
        System.out.println("init filter");
    }
    
    @Override
    public void destroy() {}
}

大佬总结

以上是大佬教程为你收集整理的在 Spring Security 中将 Azure AD 配置为 IDP全部内容,希望文章能够帮你解决在 Spring Security 中将 Azure AD 配置为 IDP所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。
标签:中将