Skip to content

Instantly share code, notes, and snippets.

@unclebean
Last active November 1, 2024 05:49
Show Gist options
  • Save unclebean/c42861c9f67410c8e512d53ed8ad3ade to your computer and use it in GitHub Desktop.
Save unclebean/c42861c9f67410c8e512d53ed8ad3ade to your computer and use it in GitHub Desktop.
entra id integration
<!-- For Maven -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
// App.js
import React from "react";
import { MsalProvider } from "@azure/msal-react";
import msalInstance from "./msalConfig";
import MainContent from "./MainContent";
function App() {
return (
<MsalProvider instance={msalInstance}>
<MainContent />
</MsalProvider>
);
}
export default App;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
@JsonIgnoreProperties(ignoreUnknown = true)
public class DirectoryObject {
private String id;
private String displayName;
private String odataType;
// Getters and Setters
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getDisplayName() {
return displayName;
}
public void setDisplayName(String displayName) {
this.displayName = displayName;
}
public String getOdataType() {
return odataType;
}
public void setOdataType(String odataType) {
this.odataType = odataType;
}
}
// FetchUserInfo.js
import React, { useEffect, useState } from "react";
import { useMsal } from "@azure/msal-react";
const FetchUserInfo = () => {
const { instance } = useMsal();
const [userInfo, setUserInfo] = useState(null);
useEffect(() => {
instance
.acquireTokenSilent({
scopes: ["user.read"],
})
.then((response) => {
fetch("https://graph.microsoft.com/v1.0/me", {
headers: {
Authorization: `Bearer ${response.accessToken}`,
},
})
.then((res) => res.json())
.then((data) => setUserInfo(data));
})
.catch((error) => console.error(error));
}, [instance]);
return (
<div>
{userInfo ? (
<div>
<h3>User Info:</h3>
<p>Name: {userInfo.displayName}</p>
<p>Email: {userInfo.userPrincipalName}</p>
</div>
) : (
<p>Loading user info...</p>
)}
</div>
);
};
export default FetchUserInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;
import java.util.List;
@Service
public class GraphApiService {
private final WebClient webClient;
@Autowired
public GraphApiService(WebClient.Builder webClientBuilder) {
this.webClient = webClientBuilder.baseUrl("https://graph.microsoft.com/v1.0").build();
}
public Mono<List<DirectoryObject>> getUserMemberOf(String userId, String accessToken) {
return webClient.get()
.uri("/users/{userId}/memberOf", userId)
.headers(headers -> headers.setBearerAuth(accessToken))
.retrieve()
.bodyToFlux(DirectoryObject.class)
.collectList();
}
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;
@Service
public class GraphApiService {
@Autowired
private AzureTokenService azureTokenService;
private final WebClient webClient = WebClient.builder()
.baseUrl("https://graph.microsoft.com/v1.0")
.defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.build();
public Mono<String> getUserGroups(String userId) {
String accessToken = azureTokenService.getAccessToken();
return webClient.get()
.uri("/users/{id}/memberOf", userId)
.header(HttpHeaders.AUTHORIZATION, "Bearer " + accessToken)
.retrieve()
.bodyToMono(String.class);
}
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;
import java.util.List;
@Service
public class GraphApiService {
private final WebClient webClient;
@Autowired
public GraphApiService(WebClient.Builder webClientBuilder) {
this.webClient = webClientBuilder.baseUrl("https://graph.microsoft.com/v1.0").build();
}
public Mono<List<DirectoryObject>> getUserMemberOf(String userId, String accessToken) {
return webClient.get()
.uri("/users/{userId}/memberOf", userId)
.headers(headers -> headers.setBearerAuth(accessToken))
.retrieve()
.bodyToFlux(DirectoryObject.class)
.collectList();
}
}
npm install @azure/msal-react @azure/msal-browser
// MainContent.js
import React from "react";
import { useMsal, useIsAuthenticated } from "@azure/msal-react";
import { InteractionType } from "@azure/msal-browser";
const MainContent = () => {
const { instance } = useMsal();
const isAuthenticated = useIsAuthenticated();
const handleLogin = () => {
instance.loginPopup({
scopes: ["user.read"], // Adjust the scopes according to your app's needs
prompt: "select_account",
}).catch(error => console.error(error));
};
const handleLogout = () => {
instance.logoutPopup({
postLogoutRedirectUri: "http://localhost:3000",
});
};
return (
<div>
{isAuthenticated ? (
<div>
<h2>Welcome, you are logged in!</h2>
<button onClick={handleLogout}>Logout</button>
</div>
) : (
<button onClick={handleLogin}>Login with Entra ID</button>
)}
</div>
);
};
export default MainContent;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.List;
@JsonIgnoreProperties(ignoreUnknown = true)
public class MemberOfResponse {
@JsonProperty("@odata.context")
private String odataContext;
@JsonProperty("value")
private List<DirectoryObject> value;
// Getters and Setters
public String getOdataContext() {
return odataContext;
}
public void setOdataContext(String odataContext) {
this.odataContext = odataContext;
}
public List<DirectoryObject> getValue() {
return value;
}
public void setValue(List<DirectoryObject> value) {
this.value = value;
}
}
// msalConfig.js
import { PublicClientApplication } from "@azure/msal-browser";
const msalConfig = {
auth: {
clientId: "<YOUR_CLIENT_ID>", // Your client ID from Azure
authority: "https://login.microsoftonline.com/<YOUR_TENANT_ID>", // Your tenant ID
redirectUri: "http://localhost:3000", // Same as the redirect URI in Azure AD
},
cache: {
cacheLocation: "sessionStorage", // Options: "localStorage" or "sessionStorage"
storeAuthStateInCookie: false,
},
};
const msalInstance = new PublicClientApplication(msalConfig);
export default msalInstance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;
import java.util.List;
@Service
public class UserService {
private final GraphApiService graphApiService;
@Autowired
public UserService(GraphApiService graphApiService) {
this.graphApiService = graphApiService;
}
public Mono<Boolean> userHasRole(String userId, String accessToken, String roleName) {
return graphApiService.getUserMemberOf(userId, accessToken)
.map(directoryObjects -> directoryObjects.stream()
.anyMatch(obj -> roleName.equalsIgnoreCase(obj.getDisplayName())));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment