使用adal auth固定时,确保弹簧支持 [英] Securing Spring backed, when fronted is secured with adal auth

查看:169
本文介绍了使用adal auth固定时,确保弹簧支持的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我们有这个包含两个部分的应用程序

So we have this application that has two parts

  1. 前端ui-使用Angular JS
  2. 后端-使用Spring Boot的REST API

使用microsoft-adal-angular6库对Azure Active Directory进行身份验证来保护前端

Front end is secured using microsoft-adal-angular6 library to authenticate with Azure Active Directory

我的问题是,保护后端安全的正确方法是什么,以便只有经过活动目录身份验证的用户才能访问API?

My question is what is the right way to secure the Back end so only active directory authenticated users can access the API?

推荐答案

我建议使用 jwt令牌 ,它作为授权"标头附加到后端的每个请求.令牌由三部分组成,其中一部分保存有关用户的数据,另一部分保存签名,因此您可以验证令牌是由受信任的源创建的.数据部分可能看起来像这样:

I would suggest to use a jwt token, that is attached to every request to your backend as 'Authorization' header. The token consists of three parts, where one is holding data about the user and one a signature, so you can validate that your token was created by a trusted source. The data part can look something like this:

{
    "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 Security 5. 您将需要那些依赖项:

On the spring side, I would suggest using Spring Security 5 with the latest configuration. You will need those dependencies:

         <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>

现在,您可以启用安全性并使用配置类对其进行配置.在内部,您可以定义请求必须具有的范围,如何对令牌进行签名以及使用路由是公开的或安全的.

Now you can enable security and configure it with a configuration class. Inside you can define which scope the request must have, how to sign the token and with route should be public or secured.


@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Value("${spring.security.oauth2.resourceserver.jwt.jwk-set-uri}")
    String jwkSetUri;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // @formatter:off
        http
            .cors().disable()
            .authorizeRequests()
            .antMatchers(("/webapp/**")).hasAuthority("SCOPE_WEBAPP")
            .antMatchers(("/admin/**")).hasRole("ADMIN")
            ...
            .and()
            .oauth2ResourceServer().jwt(jwtConfigurer -> jwtConfigurer.decoder(jwtDecoder())
            .jwtAuthenticationConverter(new CustomJwtAuthenticationConverter()))
            ...
        // @formatter:on
    }

    @Bean
    JwtDecoder jwtDecoder() {
        return NimbusJwtDecoder.withJwkSetUri(jwkSetUri).build();
    }
}

我不得不使用自定义的JwtConverter来从jwt中获取角色,但是我想这取决于您的操作方式.

I had to use a custom JwtConverter to get the roles from the jwt, but it depends on how you do it, I guess.

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();
    }
}

这使您可以基于URL保护应用程序.

This enables you to secure your application on an url basis.

jwt,JwtConverter和@EnableGlobalMethodSecurity注释中的角色使您可以保护甚至在方法级别上.

The roles in the jwt, the JwtConverter and the @EnableGlobalMethodSecurity annotation enable you to secure even on a method level.

@Transactional
@PreAuthorize("hasRole('ROLE_PROJECT_MANAGER')")
public Page<Project> findAll(Pageable pageable) {
    return projectRepository.findAll(pageable);
}

Azure Active Directory应该

Azure Active Directory should support jwt, but I don't have experience with this IDP. What I can't answer is, how you can inject custom claims like roles inside the token and where to get the jwks (Json Web Key Set), which is used to validate the token's signature.

这篇关于使用adal auth固定时,确保弹簧支持的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆