Skip to content

Instantly share code, notes, and snippets.

@unclebean
Last active December 13, 2024 08:27
Show Gist options
  • Select an option

  • Save unclebean/c4012392ace0887254ad2a7cc4377fae to your computer and use it in GitHub Desktop.

Select an option

Save unclebean/c4012392ace0887254ad2a7cc4377fae to your computer and use it in GitHub Desktop.
EntraId+Graph
import org.springframework.core.convert.converter.Converter;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.security.oauth2.server.resource.authentication.JwtGrantedAuthoritiesConverter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
public class CustomClaimConverter implements Converter<Jwt, Collection<GrantedAuthority>> {
private final JwtGrantedAuthoritiesConverter defaultGrantedAuthoritiesConverter;
public CustomClaimConverter() {
this.defaultGrantedAuthoritiesConverter = new JwtGrantedAuthoritiesConverter();
}
@Override
public Collection<GrantedAuthority> convert(Jwt jwt) {
// Start with the default authorities provided by JwtGrantedAuthoritiesConverter
Collection<GrantedAuthority> grantedAuthorities = new ArrayList<>(defaultGrantedAuthoritiesConverter.convert(jwt));
// Add custom roles from the "roles" claim
if (jwt.containsClaim("roles")) {
List<String> roles = jwt.getClaimAsStringList("roles");
if (roles != null) {
roles.forEach(role -> grantedAuthorities.add(new SimpleGrantedAuthority("ROLE_" + role)));
}
}
// Add custom permissions from a "permissions" claim, if it exists
if (jwt.containsClaim("permissions")) {
List<String> permissions = jwt.getClaimAsStringList("permissions");
if (permissions != null) {
permissions.forEach(permission -> grantedAuthorities.add(new SimpleGrantedAuthority("PERMISSION_" + permission)));
}
}
return grantedAuthorities;
}
}
import com.microsoft.aad.msal4j.*;
import java.util.Set;
@Service
public class GraphService {
public String fetchGraphData(String accessToken) {
try {
IAuthenticationResult result = ConfidentialClientApplication
.builder("YOUR_CLIENT_ID", ClientCredentialFactory.createFromSecret("YOUR_CLIENT_SECRET"))
.authority("https://login.microsoftonline.com/YOUR_TENANT_ID")
.build()
.acquireToken(ClientCredentialParameters.builder(Set.of("https://graph.microsoft.com/.default")).build())
.join();
// Use the access token
return result.accessToken();
} catch (Exception e) {
throw new RuntimeException("Failed to fetch Graph data", e);
}
}
}
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.oauth2.jwt.JwtDecoder;
import org.springframework.security.oauth2.jwt.JwtDecoders;
import org.springframework.security.oauth2.jwt.NimbusJwtDecoder;
@Configuration
public class JwtDecoderConfig {
@Bean
public JwtDecoder jwtDecoder() {
// Decode for v2.0 issuer
NimbusJwtDecoder v2Decoder = JwtDecoders.fromIssuerLocation("https://login.microsoftonline.com/{tenant-id}/v2.0");
// Decode for v1.0 issuer
NimbusJwtDecoder v1Decoder = JwtDecoders.fromIssuerLocation("https://sts.windows.net/{tenant-id}/");
return token -> {
try {
return v2Decoder.decode(token);
} catch (Exception e) {
return v1Decoder.decode(token);
}
};
}
}
import org.springframework.security.oauth2.jwt.NimbusJwtDecoder;
import org.springframework.security.oauth2.jwt.JwtDecoder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class JwtDecoderConfig {
@Bean
public JwtDecoder jwtDecoder() {
return NimbusJwtDecoder.withJwkSetUri("https://login.microsoftonline.com/{tenant-id}/discovery/v2.0/keys").build();
}
}
const loginRequest = {
scopes: ["openid", "profile", "email", "https://graph.microsoft.com/Directory.Read.All"]
};
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/admin/**").hasRole("Admin")
.anyRequest().authenticated()
.and()
.oauth2ResourceServer()
.jwt()
.jwtAuthenticationConverter(jwtAuthenticationConverter());
return http.build();
}
private JwtAuthenticationConverter jwtAuthenticationConverter() {
JwtAuthenticationConverter jwtAuthenticationConverter = new JwtAuthenticationConverter();
jwtAuthenticationConverter.setJwtGrantedAuthoritiesConverter(new CustomClaimConverter());
return jwtAuthenticationConverter;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment