1

I will apologise now if there is a really obvious answer to this!

I have a simple test project that signs a user in using openid connect and azure. The sign in and sign out work.

What I cant figure out is how to read the response body so I can determine who the logged in user is.

I am guessing there is some sort of async handler I have to add to the middleware to receive the response but I cant find any examples on how to do that. My code is in VB but I am happy with examples in C#, I just can't find any.

Can someone point me to some examples that show how the response is collected please?

Many thanks, Mike

My code is below.

signin.aspx

<%@ Page Title="" Language="VB" MasterPageFile="~/masterpage/MasterPage.master" AutoEventWireup="false" CodeFile="signin.aspx.vb" Inherits="signin" %>

<asp:Content ID="Content1" ContentPlaceHolderID="HeaderPlaceHolder" Runat="Server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="FCKBodyTopPlaceHolder" Runat="Server">
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="BodyPlaceHolder" Runat="Server">
    
         <form runat="server" >
              <div>
            <asp:Button runat="server" ID="btnSignIn" Text="Sign In" />

            <asp:Button runat="server" ID="btnSignOut" Text="Sign Out" />
                  </div>

             
             </form>
        
</asp:Content>

signin.aspx.vb

Imports System
Imports System.IO
Imports System.Web
Imports Microsoft.Owin
Imports Microsoft.Owin.Security
Imports Microsoft.Owin.Security.Cookies
Imports Microsoft.Owin.Security.OpenIdConnect
Partial Class signin
    Inherits System.Web.UI.Page

    Private Sub signin2_Load(sender As Object, e As EventArgs) Handles Me.Load
        If Not Request.IsAuthenticated Then
            btnSignIn.Visible = True
            btnSignOut.Visible = False
        Else
            btnSignIn.Visible = False
            btnSignOut.Visible = True
        End If

    End Sub

    Private Sub btnSignIn_Click(sender As Object, e As EventArgs) Handles btnSignIn.Click
        If Not Request.IsAuthenticated Then
            
                HttpContext.Current.GetOwinContext().Authentication.Challenge(New AuthenticationProperties, OpenIdConnectAuthenticationDefaults.AuthenticationType)
           
        End If
    End Sub

    Private Sub btnSignOut_Click(sender As Object, e As EventArgs) Handles btnSignOut.Click
        HttpContext.Current.GetOwinContext().Authentication.SignOut()
    End Sub
End Class

startup.vb

Imports System
Imports System.Threading.Tasks
Imports Microsoft.Owin
Imports Owin
Imports Microsoft.IdentityModel.Protocols.OpenIdConnect
Imports Microsoft.IdentityModel.Tokens
Imports Microsoft.Owin.Security
Imports Microsoft.Owin.Security.Cookies
Imports Microsoft.Owin.Security.OpenIdConnect
Imports Microsoft.Owin.Security.Notifications


<Assembly: OwinStartup(GetType(WEBCOMLogin.Startup))>
Namespace WEBCOMLogin
    Public Class Startup
        Private clientId As String = System.Configuration.ConfigurationManager.AppSettings("ClientId")
        Private redirectUri As String = System.Configuration.ConfigurationManager.AppSettings("RedirectUri")
        Shared tenant As String = System.Configuration.ConfigurationManager.AppSettings("Tenant")
        Private authority As String = String.Format(System.Globalization.CultureInfo.InvariantCulture, System.Configuration.ConfigurationManager.AppSettings("Authority"), tenant)

        Public Sub Configuration(ByVal app As IAppBuilder)
            app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType)
            app.UseCookieAuthentication(New CookieAuthenticationOptions())
            app.UseOpenIdConnectAuthentication(New OpenIdConnectAuthenticationOptions With {
                .ClientId = clientId,
                .Authority = authority,
                .RedirectUri = redirectUri,
                .PostLogoutRedirectUri = redirectUri,
                .Scope = OpenIdConnectScope.OpenIdProfile,
                .ResponseType = OpenIdConnectResponseType.IdToken,
                .ResponseMode = OpenIdConnectResponseMode.FormPost,
                .Notifications = New OpenIdConnectAuthenticationNotifications With {
                    .AuthenticationFailed = AddressOf OnAuthenticationFailed
                }
            })

        End Sub

        Private Function OnAuthenticationFailed(ByVal context As AuthenticationFailedNotification(Of OpenIdConnectMessage, OpenIdConnectAuthenticationOptions)) As Task
            context.HandleResponse()
            context.Response.Redirect("/?errormessage=" & context.Exception.Message)
            Return Task.FromResult(0)
        End Function
    End Class
End Namespace

Edit: Added screenshot of claims

Screen shot of claims

Claims Details

Mike
  • 45
  • 7

1 Answers1

1

with OpenID Connect the user details are returned back in the Id-token and the easiest way to get access to who the user is is to either look in the HttpContext.Current.User object.

You should not try to access it your self from the headers. Because the actual token data is never visible to your browser, instead it is retrieved by the OpenIDConnect handler in the background.

Tore Nestenius
  • 16,431
  • 5
  • 30
  • 40
  • Thanks for the advice. I've just tried checking the output of HttpContext.Current.User.Identity.Name but it comes back blank. However httpcontext.current.user.Identity.IsAuthenticated returns as true. Could it be down to the ResponseType I am using? – Mike Aug 06 '21 at 15:02
  • If it says you are authenticated, then you have come a long way on the way to your goal. you could paste a sample copy of your ID-token and also a sample of the claims associated in the user. See the picture in the question I just answered here https://stackoverflow.com/questions/68682161/ – Tore Nestenius Aug 06 '21 at 15:09
  • I do feel like i am making progress. I've added a screen shot to the original post. Unfortunately it looks like the problem is that there is no claim. I've run out of time for today but will carry on investigating on Monday. – Mike Aug 06 '21 at 15:52
  • In the picture you need to expand the "Result view" to see the actual claims. Also do post a sample token content (ID-token) – Tore Nestenius Aug 06 '21 at 16:11
  • Sorry, added extra screen shot with the expanded claim. Next stupid question, how do I find the token content? Would it be the content of httpcontext.current.GetOwinContext.Response.body? – Mike Aug 09 '21 at 09:25
  • 1
    Not sure how do to in old ASP.NET , but in ASP.NET Core I would get the received token using var accessToken = await HttpContext.GetTokenAsync("access_token"); There are also various event handlers that you could use to get it (from the OpenIDConnect auth owin handler) – Tore Nestenius Aug 09 '21 at 09:49
  • Thank you, that gives me a starting point to do more research. – Mike Aug 09 '21 at 10:26
  • 1
    you can also set "SaveToken=true" in UseOpenIdConnectAuthentication and then the tokens will be saved inside the session cookie. See this question https://stackoverflow.com/questions/46319114/how-to-get-access-token-from-httpcontext-using-owin-and-mvc-5 – Tore Nestenius Aug 09 '21 at 10:58
  • I'm sure this will be the answer! I've just got to work out how to implement it and test ;-) GetTokenAsync doesn't trigger the authentication so i just need to work on that bit. – Mike Aug 10 '21 at 07:50
  • GetTokenAsync won't trigger a authentication if the token is missing or not there... – Tore Nestenius Aug 10 '21 at 09:08