Spring boot 使用adal auth固定弹簧靠背(正面时)

Spring boot 使用adal auth固定弹簧靠背(正面时),spring-boot,adal,Spring Boot,Adal,所以我们有这个应用程序,它有两个部分 前端用户界面-使用Angular JS 后端-使用Spring引导的rest api 前端使用microsoft-adal-angular6库进行安全保护,以通过Azure Active Directory进行身份验证 我的问题是,保护后端的正确方法是什么,这样只有经过active directory身份验证的用户才能访问API?我建议使用,它作为“授权”头附加到后端的每个请求。令牌由三部分组成,其中一部分保存有关用户的数据,另一部分保存签名,因此您可以验证

所以我们有这个应用程序,它有两个部分

  • 前端用户界面-使用Angular JS
  • 后端-使用Spring引导的rest api
  • 前端使用microsoft-adal-angular6库进行安全保护,以通过Azure Active Directory进行身份验证

    我的问题是,保护后端的正确方法是什么,这样只有经过active directory身份验证的用户才能访问API?

    我建议使用,它作为“授权”头附加到后端的每个请求。令牌由三部分组成,其中一部分保存有关用户的数据,另一部分保存签名,因此您可以验证令牌是否由可信源创建。数据部分可以如下所示:

    {
        "iss": "Online JWT Builder",
        "iat": 1580283510,
        "exp": 1611819510,
        "aud": "www.example.com",
        "sub": "jrocket@example.com",
        "GivenName": "Johnny",
        "roles": ["PROJECT_MANAGER", "ADMIN"]
        "scope": "WEBAPP"
    }
    
    在spring方面,我建议使用最新配置的SpringSecurity5。 您将需要这些依赖项:

             <dependency>
                <groupId>org.springframework.security</groupId>
                <artifactId>spring-security-config</artifactId>
                <version>5.x.x.RELEASE</version>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.security</groupId>
                <artifactId>spring-security-oauth2-jose</artifactId>
                <version>5.x.x.RELEASE</version>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.security</groupId>
                <artifactId>spring-security-oauth2-resource-server</artifactId>
                <version>5.x.x.RELEASE</version>
    
    我不得不使用一个定制的JwtConverter从jwt中获取角色,但我想这取决于你是如何做到的

    public class CustomJwtAuthenticationConverter implements Converter<Jwt, AbstractAuthenticationToken> {
    
        private final JwtGrantedAuthoritiesConverter defaultGrantedAuthoritiesConverter = new JwtGrantedAuthoritiesConverter();
    
        public CustomJwtAuthenticationConverter() {
        }
    
        @Override
        public AbstractAuthenticationToken convert(@NotNull final Jwt jwt) {
            Collection<GrantedAuthority> authorities = Stream
                    .concat(defaultGrantedAuthoritiesConverter.convert(jwt).stream(), extractResourceRoles(jwt).stream())
                    .collect(Collectors.toSet());
            return new JwtAuthenticationToken(jwt, authorities);
        }
    
        private static Collection<? extends GrantedAuthority> extractResourceRoles(final Jwt jwt) {
            Collection<String> userRoles = jwt.getClaimAsStringList("roles");
            if (userRoles != null)
                return userRoles
                        .stream()
                        .map(role -> new SimpleGrantedAuthority("ROLE_" + role))
                        .collect(Collectors.toSet());
            return Collections.emptySet();
        }
    }
    
    Azure Active Directory应该可以,但我没有使用此IDP的经验。 我无法回答的是,如何在令牌中注入自定义声明,如角色,以及从何处获取用于验证令牌签名的jwks(Json Web密钥集)

    public class CustomJwtAuthenticationConverter implements Converter<Jwt, AbstractAuthenticationToken> {
    
        private final JwtGrantedAuthoritiesConverter defaultGrantedAuthoritiesConverter = new JwtGrantedAuthoritiesConverter();
    
        public CustomJwtAuthenticationConverter() {
        }
    
        @Override
        public AbstractAuthenticationToken convert(@NotNull final Jwt jwt) {
            Collection<GrantedAuthority> authorities = Stream
                    .concat(defaultGrantedAuthoritiesConverter.convert(jwt).stream(), extractResourceRoles(jwt).stream())
                    .collect(Collectors.toSet());
            return new JwtAuthenticationToken(jwt, authorities);
        }
    
        private static Collection<? extends GrantedAuthority> extractResourceRoles(final Jwt jwt) {
            Collection<String> userRoles = jwt.getClaimAsStringList("roles");
            if (userRoles != null)
                return userRoles
                        .stream()
                        .map(role -> new SimpleGrantedAuthority("ROLE_" + role))
                        .collect(Collectors.toSet());
            return Collections.emptySet();
        }
    }
    
    @Transactional
    @PreAuthorize("hasRole('ROLE_PROJECT_MANAGER')")
    public Page<Project> findAll(Pageable pageable) {
        return projectRepository.findAll(pageable);
    }