Elkészítette az ügyfélalkalmazás-objektumot. Most egy jogkivonat beszerzésére használva meghívhat egy webes API-t. A ASP.NET vagy ASP.NET Core-ban a webes API meghívása a vezérlőben történik:
A Microsoft.Identity.Web bővítménymetelyeket ad hozzá, amelyek kényelmi szolgáltatásokat nyújtanak a Microsoft Graph vagy egy alsóbb rétegbeli webes API meghívásához. Ezeket a módszereket részletesen ismertetjük a webes API-kat hívó webalkalmazásban : API meghívása. Ezekkel a segítő módszerekkel nem kell manuálisan beszereznie egy jogkivonatot.
Ha azonban manuálisan szeretne beszerezni egy jogkivonatot, az alábbi kód a Microsoft.Identity.Web otthoni vezérlőben való használatára mutat példát. Meghívja a Microsoft Graphot a REST API használatával (a Microsoft Graph SDK helyett). Általában nem kell jogkivonatot lekérnie, létre kell készítenie egy engedélyezési fejlécet, amelyet hozzáad a kéréshez. Az engedélyezési fejléc lekéréséhez függőséginjektálással injektálja a IAuthorizationHeaderProvider
szolgáltatást a vezérlő konstruktorában (vagy az oldalkonstruktorban, ha Blazort használ), és a vezérlőműveletekben használja. Ez az interfész olyan metódusokkal rendelkezik, amelyek a protokollt (Bearer, Pop, ...) és egy jogkivonatot tartalmazó sztringet hoznak létre. Ha le szeretne kapni egy engedélyezési fejlécet, amely meghív egy API-t a felhasználó nevében, használja a (CreateAuthorizationHeaderForUserAsync
) parancsot. Ha egy engedélyezési fejlécet szeretne lekérni egy alsóbb rétegbeli API-nak az alkalmazás nevében történő meghívásához, használjon (CreateAuthorizationHeaderForAppAsync
) egy démonforgatókönyvet.
A vezérlő metódusait egy [Authorize]
attribútum védi, amely biztosítja, hogy csak hitelesített felhasználók használják a webalkalmazást.
[Authorize]
public class HomeController : Controller
{
readonly IAuthorizationHeaderProvider authorizationHeaderProvider;
public HomeController(IAuthorizationHeaderProvider authorizationHeaderProvider)
{
this.authorizationHeaderProvider = authorizationHeaderProvider;
}
// Code for the controller actions (see code below)
}
ASP.NET Core függőséginjektálással teszi IAuthorizationHeaderProvider
elérhetővé.
Az alábbi egyszerűsített kód a HomeController
Microsoft Graph meghívására szolgáló jogkivonatot kap:
[AuthorizeForScopes(Scopes = new[] { "user.read" })]
public async Task<IActionResult> Profile()
{
// Acquire the access token.
string[] scopes = new string[]{"user.read"};
string accessToken = await authorizationHeaderProvider.CreateAuthorizationHeaderForUserAsync(scopes);
// Use the access token to call a protected web API.
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", accessToken);
string json = await client.GetStringAsync(url);
}
Az ehhez a forgatókönyvhöz szükséges kód jobb megértéséhez tekintse meg az ms-identity-aspnetcore-webapp-tutorial oktatóanyag 2. fázisának (2-1-Web app Calls Microsoft Graph) lépését.
A AuthorizeForScopes
vezérlőművelet (vagy Razor-sablon használata esetén a Razor-oldal) tetején található attribútumot a Microsoft.Identity.Web biztosítja. Biztosítja, hogy a felhasználót szükség esetén és fokozatosan hozzájárulást kérnek.
Más összetett változatok is léteznek, például:
- Több API meghívása.
- Növekményes hozzájárulás és feltételes hozzáférés feldolgozása.
Ezeket a speciális lépéseket a 3-WebApp-multi-API-k oktatóanyagának 3. fejezete ismerteti.
A ASP.NET kódja a ASP.NET Core esetében látható kódhoz hasonló:
- Egy attribútum által
[Authorize]
védett vezérlőművelet kinyeri a vezérlő tagjának ClaimsPrincipal
bérlőazonosítóját és felhasználói azonosítóját (ASP.NET használja HttpContext.User
). Ez biztosítja, hogy csak hitelesített felhasználók használhatják az alkalmazást.
A Microsoft.Identity.Web bővítő metódusokat ad a vezérlőhöz, amelyek kényelmi szolgáltatásokat nyújtanak a Microsoft Graph vagy egy alsóbb rétegbeli webes API meghívásához, vagy egy engedélyezési fejléc vagy akár egy jogkivonat lekéréséhez. Az API-k közvetlen meghívásához használt módszerek részletes ismertetését a webes API-kat hívó webalkalmazások ismertetik: API meghívása. Ezekkel a segítő módszerekkel nem kell manuálisan beszereznie egy jogkivonatot.
Ha azonban manuálisan szeretne beszerezni egy jogkivonatot vagy létrehozni egy engedélyezési fejlécet, az alábbi kód bemutatja, hogyan használhatja ezt a Microsoft.Identity.Web-et egy vezérlőben. A Microsoft Graph SDK helyett a REST API használatával hív meg egy API-t (Microsoft Graph).
Az engedélyezési fejléc lekéréséhez egy IAuthorizationHeaderProvider
szolgáltatást kap a vezérlőtől egy bővítménymetódus GetAuthorizationHeaderProvider
használatával. Ha le szeretne kapni egy engedélyezési fejlécet, amely meghív egy API-t a felhasználó nevében, használja a következőt CreateAuthorizationHeaderForUserAsync
: . Ha egy engedélyezési fejlécet szeretne lekérni, amely meghív egy alsóbb rétegbeli API-t az alkalmazás nevében, egy démonforgatókönyvben használja a következőt CreateAuthorizationHeaderForAppAsync
: .
Az alábbi kódrészlet a Microsoft Graph REST API-ként való meghívásához szükséges engedélyezési fejlécet kapó műveletét HomeController
mutatja be:
[Authorize]
public class HomeController : Controller
{
[AuthorizeForScopes(Scopes = new[] { "user.read" })]
public async Task<IActionResult> Profile()
{
// Get an authorization header.
IAuthorizationHeaderProvider authorizationHeaderProvider = this.GetAuthorizationHeaderProvider();
string[] scopes = new string[]{"user.read"};
string authorizationHeader = await authorizationHeaderProvider.CreateAuthorizationHeaderForUserAsync(scopes);
// Use the access token to call a protected web API.
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", authorizationHeader);
string json = await client.GetStringAsync(url);
}
}
Az alábbi kódrészlet a Microsoft Graph REST API-ként való meghívásához szükséges hozzáférési jogkivonatot kapó műveletét HomeController
mutatja be:
[Authorize]
public class HomeController : Controller
{
[AuthorizeForScopes(Scopes = new[] { "user.read" })]
public async Task<IActionResult> Profile()
{
// Get an authorization header.
ITokenAcquirer tokenAcquirer = TokenAcquirerFactory.GetDefaultInstance().GetTokenAcquirer();
string[] scopes = new string[]{"user.read"};
string token = await tokenAcquirer.GetTokenForUserAsync(scopes);
// Use the access token to call a protected web API.
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", $"Bearer {token}");
string json = await client.GetStringAsync(url);
}
}
A Java-mintában az API-t hívó kód az getUsersFromGraph
AuthPageController.java#L62 metódusban található.
A metódus megkísérli meghívni a metódust getAuthResultBySilentFlow
. Ha a felhasználónak több hatókörhöz kell hozzájárulnia, a kód feldolgozza az MsalInteractionRequiredException
objektumot, hogy megtámadja a felhasználót.
@RequestMapping("/msal4jsample/graph/me")
public ModelAndView getUserFromGraph(HttpServletRequest httpRequest, HttpServletResponse response)
throws Throwable {
IAuthenticationResult result;
ModelAndView mav;
try {
result = authHelper.getAuthResultBySilentFlow(httpRequest, response);
} catch (ExecutionException e) {
if (e.getCause() instanceof MsalInteractionRequiredException) {
// If the silent call returns MsalInteractionRequired, redirect to authorization endpoint
// so user can consent to new scopes.
String state = UUID.randomUUID().toString();
String nonce = UUID.randomUUID().toString();
SessionManagementHelper.storeStateAndNonceInSession(httpRequest.getSession(), state, nonce);
String authorizationCodeUrl = authHelper.getAuthorizationCodeUrl(
httpRequest.getParameter("claims"),
"User.Read",
authHelper.getRedirectUriGraph(),
state,
nonce);
return new ModelAndView("redirect:" + authorizationCodeUrl);
} else {
mav = new ModelAndView("error");
mav.addObject("error", e);
return mav;
}
}
if (result == null) {
mav = new ModelAndView("error");
mav.addObject("error", new Exception("AuthenticationResult not found in session."));
} else {
mav = new ModelAndView("auth_page");
setAccountInfo(mav, httpRequest);
try {
mav.addObject("userInfo", getUserInfoFromGraph(result.accessToken()));
return mav;
} catch (Exception e) {
mav = new ModelAndView("error");
mav.addObject("error", e);
}
}
return mav;
}
// Code omitted here
A Node.js mintában a jogkivonatot beszerző kód az acquireToken
osztály metódusában AuthProvider
található.
acquireToken(options = {}) {
return async (req, res, next) => {
try {
const msalInstance = this.getMsalInstance(this.msalConfig);
/**
* If a token cache exists in the session, deserialize it and set it as the
* cache for the new MSAL CCA instance. For more, see:
* https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-node/docs/caching.md
*/
if (req.session.tokenCache) {
msalInstance.getTokenCache().deserialize(req.session.tokenCache);
}
const tokenResponse = await msalInstance.acquireTokenSilent({
account: req.session.account,
scopes: options.scopes || [],
});
/**
* On successful token acquisition, write the updated token
* cache back to the session. For more, see:
* https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-node/docs/caching.md
*/
req.session.tokenCache = msalInstance.getTokenCache().serialize();
req.session.accessToken = tokenResponse.accessToken;
req.session.idToken = tokenResponse.idToken;
req.session.account = tokenResponse.account;
res.redirect(options.successRedirect);
} catch (error) {
if (error instanceof msal.InteractionRequiredAuthError) {
return this.login({
scopes: options.scopes || [],
redirectUri: options.redirectUri,
successRedirect: options.successRedirect || '/',
})(req, res, next);
}
next(error);
}
};
}
Ez a hozzáférési jogkivonat ezután a végpontra /profile
irányuló kérések kezelésére szolgál:
router.get('/profile',
isAuthenticated, // check if user is authenticated
async function (req, res, next) {
try {
const graphResponse = await fetch(GRAPH_ME_ENDPOINT, req.session.accessToken);
res.render('profile', { profile: graphResponse });
} catch (error) {
next(error);
}
}
);
A Python-mintában az API-t meghívó kód app.py.
A kód megpróbál jogkivonatot lekérni a jogkivonat-gyorsítótárból. Ha nem tud jogkivonatot lekérni, átirányítja a felhasználót a bejelentkezési útvonalra. Ellenkező esetben meghívhatja az API-t.
@app.route("/call_downstream_api")
def call_downstream_api():
token = auth.get_token_for_user(app_config.SCOPE)
if "error" in token:
return redirect(url_for("login"))
# Use access token to call downstream api
api_result = requests.get(
app_config.ENDPOINT,
headers={'Authorization': 'Bearer ' + token['access_token']},
timeout=30,
).json()
return render_template('display.html', result=api_result)