IdentityModel OIDC Client Log Out - native

I've a native Windows Client application which is authenticating user against Identity Server. Login Works fine. However, I'm not able to sign out the user.
Here is the link of the source code that I am using
I tried logoutAsync method with no luck. Once user is signed in, whenever I start the application and click login it automatically sign the user in.

In the sample you provided code inside LogoutButton_Click is commented out.
private async void LogoutButton_Click(object sender, EventArgs e)
{
// await _oidcClient.LogoutAsync(trySilent: Silent.Checked);
// AccessTokenDisplay.Clear();
// OtherDataDisplay.Clear();
}

Related

Blazor WASM standalone project reauthentication for multiple browser tabs after logout

I have implemented authorization with JWT auth on our blazor WASM project. All was well - logging in and logging out...until
Scenario:
I noticed that if I duplicated my 'logged in (authenticated identity user) tab', now having two valid authorized user tabs open. In the first tab I log out: I am re-directed to the login page, the stored token is gone, everything seems ok - but when I go to the second tab and click to go to a new page(within the tab) I am able to do so. When I debug and check the auth state.. it still has the validated identity user!
Expected Results:
When I logout in the first autenticated tab, I expect the auth state of the second tab to also be deauthenticated.
Error Messages:
Currently none
What I have tried:
I searched around for someone solving the same thing for Blazor WASM standalone apps. I did come across this guy's video where he describes most people are using the AuthenticationStateProvider wrong by injecting it directly instead of using a cascading parameter. He actually then demonstates the exact issue I am having - but then proceeds to solve it with a Balzor Server class library(using RevalidateServerAuthenticationStateProvider with some custom code on the ValidateAuthenticationStateAsync function)! Not a WASM solution! Link to his video: https://www.youtube.com/watch?v=42O7rECc87o&list=WL&index=37&t=952s - 13:23 he demonstrates the issue I have attempted to depict.
Code of my logout sequence:
To start - when you click the logout button - I redirect to a logout page. We will start here:
Logout.Razor.cs
[CascadingParameter]
public Task<AuthenticationState> AuthenticationStateTask { get; set; }
protected override async Task OnInitializedAsync()
{
await AuthService.Logout();
var authState = await AuthenticationStateTask;
var user = authState.User;
if (!user.Identity.IsAuthenticated)
{
NavManager.NavigateTo("/");
}
}
You can see you then are waiting for the AuthService to log you out.
AuthService.cs
private readonly AuthenticationStateProvider _authStateProvider;
public async Task Logout()
{
await _localStorage.RemoveItemAsync("authToken");
await ((CustomAuthStateProvider)_authStateProvider).NotifyUserLogout();
_client.DefaultRequestHeaders.Authorization = null;
}
Then you are waiting on the CustomAuthStateProvider:AuthenticationStateProdiver to notify that the state has changed.
CustomAuthStateProvider.cs
_anonymous = new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity()));
public async Task NotifyUserLogout()
{
var authState = Task.FromResult(_anonymous);
NotifyAuthenticationStateChanged(authState);
}
At this point in the active page we are logged out and redirected to the login page.
I was hoping there is some browser session option for the authstate I am missing or there is some microsoft documentation of handling this situation on WASM projects - but my peanut brain can't seem to find it.
Additional Information: I am purely only using the AuthenticationStateProdiver for a custom login.
I am not using OidcAuthentication or MsalAuthentication services.
This is a standlone WASM app with a completely decoupled API. All .net6 living on azure.
Looking forward to see if anyone else has this issue!
BR,
MP

Android Google Sign-In

I need to enable server-side access to Google Drive. In this case a person is using his Android device. As far as I understood the steps are as follows:
1. Create GoogleSignInOptions
2. Using the GoogleSignInOptions create GoogleSignInAccount
3. Getting authCode from GoogleSignInAccount
4. Exchange the authCode for access/refresh/ID tokens
I am stuck on step 3. I followed the well-described tutorials without any success - https://developers.google.com/identity/sign-in/android/offline-access, https://developers.google.com/identity/sign-in/android/sign-in#configure_google_sign-in_and_the_googleapiclient_object
Here is the code that initialize sign-in process:
final GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestScopes(new Scope(Scopes.DRIVE_APPFOLDER))
.requestServerAuthCode(backend_server_web_client_id)
.build();
GoogleSignInClient google_api_client = GoogleSignIn.getClient(context, gso);
activity.startActivityForResult(google_api_client.getSignInIntent(), RC_SIGN_IN);
Here is the code that handles the sign-in result:
// data is the intent from onActivityResult callback
Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data);
if (task.isComplete())
handle(task);
else {
task.addOnCompleteListener(new OnCompleteListener<GoogleSignInAccount>() {
#Override
public void onComplete(#NonNull Task<GoogleSignInAccount> task) {
handle(task);
}}
});
}
And finally here is the handle function where is the problem:
public void handle(Task<GoogleSignInAccount> task) {
try {
GoogleSignInAccount account = task.getResult(ApiException.class);
} catch (ApiException e) {
//I'm always getting this exception with status code 10, which means DEVELOPER ERROR. Keys in Google API console are checked multiple times.
}
}
In handle function I'm always getting an exception with status code 10, which means DEVELOPER_ERROR. Keys in Google API console are checked multiple times. Code was rewritten few times.... I really have no idea what could be wrong.
Thank you :)
You might have forgotten to configure Google API Console. Follow the instructions:
https://developers.google.com/identity/sign-in/android/start-integrating
You see to create OAuth client ID for Android with corresponding package name and signing certificate's SHA1. You do NOT have to enter this key anywhere in the code. It just have to exist in Google API Console.

Logging out the user from other computers (that he logged in before) when he logs in from another computer

I have a web application that employees log in to do stuff. What Im trying to achieve is: When a user logs in from a computer, if he is already logged in on another computer, that must be logged out. The web app is MVC Asp.Net Core 2.2 Code first. I have added a signInManager in startup and edited the PasswordSignInAsync method. I login the system from two different devices. When I click something on the screen from the first computer that I loggedin, it redirects to logout. It seems like working. But Im not sure if this is the right way of doing this. The code I added is: await UserManager.UpdateSecurityStampAsync(user); Inside PasswordSignInAsync method.
Inside the startup class ConfigureServices method I added
'services.AddIdentity<ApplicationUser, ApplicationRole>()
.AddSignInManager<SignInManagerX>()'
Then in SignInManagerX class which is inherited from SignInManager I overrided the PasswordSignInAsync
public override async Task<SignInResult>
PasswordSignInAsync(ApplicationUser user, string password,
bool isPersistent, bool lockoutOnFailure)
{
if (user == null)
{
throw new ArgumentNullException(nameof(user));
}
var attempt = await CheckPasswordSignInAsync(user, password,
lockoutOnFailure);
//Here is added
if (attempt.Succeeded)
{
await UserManager.UpdateSecurityStampAsync(user);
}
//Add end
return attempt.Succeeded
? await SignInOrTwoFactorAsync(user, isPersistent)
: attempt;
}
Is this the right way ? or I should add a table to db for logins which holds the info if the user is already logged in on another Ip. Then Logging out that user from all computers if the last and current login attempt is true ?
Yes , the primary purpose of the SecurityStamp is to enable sign out everywhere.
The basic idea is that whenever something security related is changed on the user, like a password, it is a good idea to automatically invalidate any existing sign in cookies, so if your password/account was previously compromised, the attacker no longer has access.
Reference : https://stackoverflow.com/a/19505060/5751404
You can set validateInterval to TimeSpan.Zero for immediate logout .

Log the logins to the various applications that identityserver manages

We've got a lot of sites with common authentication by thinktecture identityserver v2.
Now we would like to have a log of the logins to the sites. We've got a custom IUserRepository where we could log a user login in, but how would we goahead and grab the site a user is loggin into?
And when we jump from one site to another - how could that be logged
In case there's no built in support for this, where is the best place to modify the code?
It seems like it could be done in the WSFederationController and in the Issue method I could get the realm based on the uri.
public ActionResult Issue()
{
Tracing.Start("WS-Federation endpoint.");
if (!ConfigurationRepository.WSFederation.Enabled && ConfigurationRepository.WSFederation.EnableAuthentication)
{
return new HttpNotFoundResult();
}
var message = WSFederationMessage.CreateFromUri(HttpContext.Request.Url);
// sign in
var signinMessage = message as SignInRequestMessage;
if (signinMessage != null)
{
// Is this a good place to log current user and the application the user is loggin into to db???
// or does Thinktecture have some build in functionaltiy for this?
return ProcessWSFederationSignIn(signinMessage, ClaimsPrincipal.Current);
}
Larsi

Facebook C# SDK: OAuth 2 in Silverlight 4 browser app

I'm completely newbie at authentication proccess with OAuth (I'm trying to make use of OAuth 2, exactly), and the example I am following to authenticate by using Facebook SDK latest release says that this code snippet should work for C# .NET environments (http://blog.prabir.me/post/Facebook-CSharp-SDK-Writing-your-first-Facebook-Application.aspx):
webBrowser.Navigate(loginUrl);
private void webBrowser_Navigated(object sender, WebBrowserNavigatedEventArgs e)
{
FacebookOAuthResult result;
if (FacebookOAuthResult.TryParse(e.Url, out result))
{
if (result.IsSuccess)
{
var accesstoken = result.AccessToken;
}
else
{
var errorDescription = result.ErrorDescription;
var errorReason = result.ErrorReason;
}
}
}
Since I am programming a browser SL app, the WebBrowser control displays nothing, so I am not either able to catch the response, how could I do something equivalent to that in my app? Or how could I manage to complete the authentication proccess if there is no equivalent way? Thanks!
A suggestion: Why don't you try to parse the WebResponse when you receive it as opposed to listening for the event?
I use Facebook OAuth in my web app. It is nothing but a series of URL posts with the correct parameters.
Take a look at this post: Login using Facebook Problem after logging out (All the details are in the answer and comments)
Here are the brief steps:
Call the Facebook OAuth Dialog URL with your AppId, redirect url, and permissions. Request_type should be "code"
When the user logs in and authorizes you application, they will be redirected to the redirect url with a "code" querystring parameter.
Take the value of the code parameter and make another call to Facebook to get the token.
Use this token to make calls on the user's behalf.