We would like to implement functionality where user should be logged silently over Single sign-on. The user go to the application A and log into. Now he goes to the application B, which is using the same tenant as application A. At this moment to log into the application B, it is necessary by user to click on Login button to start the Challenge which handle the whole OpenID Connect protocol exchange.
[HttpGet]
public IActionResult SignIn()
{
var redirectUrl = Url.Action(nameof(HomeContrsioller.Index), "Home");
return Challenge(new AuthenticationProperties { RedirectUri = redirectUrl },
OpenIdConnectDefaults.AuthenticationScheme);
}
The idea here was to utilize Authorize attribute.
[Authorize]
public IActionResult Index()
{
return View();
}
The problem with this attribute is that per default the attribute redirects to the login UI when the user isn't logged in. The desired behavior here is to try to silently authenticate user, when the authentication isn't possible, ignore it.
I tried to disable to automatic challenge like described here but without success.
You can try embedding an iframe on an anonymous page that has the src set to the signin route. Make sure when your challenge fires you set prompt=none
You can squash any errors that come back from the signin request like interaction_required and acheive a silent single sign on when it works
The Thing i want to do is , We have a user who is logged in a device .We have to restrict that user to login from other device.
To Login into Other device he should have to log out from the first device.
I have tried to create authentication token via web API.
Every time a user login ,a new oath token is generally passed in the request headers. (Token would be expire on logout.)
If Same User try to login from other device a new Oath token would be generated
is there anyway to check if a token is already assigned to that user then do not allow him to login
What if,
1.user close the working tab or browser
2.or He navigate to other web page by changing the URL
Are there other solutions to ensure one concurrent login per user ?
This should be simple enough to make sure a user have only one login at a time.
Steps to do would be (ASP.NET/ASP.NET MVC):
Step 1: As soon as user login, check if session for this user already exists.
Step 2: If Session already exists, delete the on going session (Here you can also prompt a message to user if he wants to stop currently going session and start a new one.)
Step 3: On User's action you may delete current session and start a new session for the user.
Step 4: If there is no current session going on, you can simply create a new one .
Update:
For ASP.NET WEB API
Here you have to use Authentication token.
On login you can provide authentication token to user.
On Relogin you can check if token is already issued for this user, and accordingly perform your action.
Hope this helps. Let me know if you have queries.
I assume you know how to code above, if not let me know.
I currently have a website where I am trying to implement the OAuth server framework. The website is currently a combination of Web Forms (not MVC) and Web API 2. For the purposes of what I am trying to do, we cannot change the overall architecture of the system.
So far, I have OAuth working via the Web API for validating clients, generating access tokens, and handling refresh tokens.
The last piece I am trying to implement is the Authorize Code workflow. This will allow us to grant access to our application so integration tools can access our APIs without having to locally store the user credentials.
My understanding of how it should function is the following:
User is directed to the AuthorizeEndpointPath that I define in the Startup.Auth file
User either sees a login page (if they don't already have an authentication cookie for the website), or they see a special page where they have to grant permission to access the account (similar to what Google has)
Once the user clicks the "grant" button, the OWIN middleware will process the request, and redirect them back to the original client URL that requested access
However, after all of my configuration, whenever I access the AuthorizeEndpointPath directly, the "grant access permission" page is never actually displayed.
I've ensured the following configuration, but there isn't much documentation on what the correct configuration is.
var oAuthServerOptions = new OAuthAuthorizationServerOptions()
{
AllowInsecureHttp = true,
TokenEndpointPath = new PathString("/api/token"),
AuthorizeEndpointPath = new PathString("/LoginAuthorize.aspx"),
//AuthorizeEndpointPath = new PathString("/api/authorize"),
AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(10),
Provider = new ApiAuthorizationServerProvider(),
RefreshTokenProvider = new ApiRefreshTokenProvider(),
AuthorizationCodeProvider = new ApiAuthoirzationCodeProvider()
};
Currently the "AuthorizeEndpointPath" property maps to an actual page, where I ask the user confirmation, but that page is not being displayed at all
Through debugging, I can see the framework hits the following method even before the authorization page would be loaded
ValidateClientRedirectUri(OAuthValidateClientRedirectUriContext context)
I have tried to overload that method, and one of 2 things happens. If I make a call to context.Validated();, the user is immediately redirected without the authorization page being displayed. If don't "validate" the redirect URI, then a blank page is displayed indicating an "invalid_request".
So the big question is how do I actually make OWIN display my custom authorization page?
When the authorization page is finally displayed, what would I need to do when the user clicks on the "grant" button. Is there any configuration I need to setup, or any calls to OWIN I need to make?
Also, how do I ensure the user authenticates before that page is displayed? Do I simply have my code redirect the user to the login page if they are not logged in? If so, how will OWIN handle the real redirect back to the client (if the user would be redirected to the authorization page once they login)?
Finally, once this is all configured properly, will I still be able to support the current OAuth workflow I have of allowing clients to manually pass in their credentials for the "token" API? The reason I ask is because we also have mobile apps that have their own sign-in screen, and will be using OAuth to connect (in addition to other web-based clients).
I had a question that turned out to be similar to yours.
So, after quite some searching online, I got some success by searching github. Apparently, OAuthAuthorizationServerProvider offers AuthorizeEndpoint and that method should be used for both "Hey, you're not authorized, go log in you!" as well as for "Ahh, okay you're cool, here's an authorization code.". I had expected that OAuthAuthorizationServerProvider would have two separate methods for that, but it doesn't. That explains why on github, I find some projects that implement AuthorizeEndpoint in a rather peculiar way. I've adopted this. Here's an example:
public override async Task AuthorizeEndpoint(OAuthAuthorizeEndpointContext context)
{
if (context.Request.User != null && context.Request.User.Identity.IsAuthenticated)
{
var redirectUri = context.Request.Query["redirect_uri"];
var clientId = context.Request.Query["client_id"];
var authorizeCodeContext = new AuthenticationTokenCreateContext(
context.OwinContext,
context.Options.AuthorizationCodeFormat,
new AuthenticationTicket(
(ClaimsIdentity)context.Request.User.Identity,
new AuthenticationProperties(new Dictionary<string, string>
{
{"client_id", clientId},
{"redirect_uri", redirectUri}
})
{
IssuedUtc = DateTimeOffset.UtcNow,
ExpiresUtc = DateTimeOffset.UtcNow.Add(context.Options.AuthorizationCodeExpireTimeSpan)
}));
await context.Options.AuthorizationCodeProvider.CreateAsync(authorizeCodeContext);
context.Response.Redirect(redirectUri + "?code=" + Uri.EscapeDataString(authorizeCodeContext.Token));
}
else
{
context.Response.Redirect("/account/login?returnUrl=" + Uri.EscapeDataString(context.Request.Uri.ToString()));
}
context.RequestCompleted();
}
Source: https://github.com/wj60387/WebApiOAUthBase/blob/master/OwinWebApiBase/WebApiOwinBase/Providers/OAuthServerProvider.cs
You create a separate login page at /account/login. What this does is sign the user in. If your WebAPI uses cookie-based authentication, you can just redirect the user back to the AuthorizeEndpoint again. If you use access tokens, your login page has to make a request to `AuthorizeEndpoint' with the access token to obtain an authorization code. (Don't give the access token to the third party. Your login page requests the authorization code and sends that back.) In other words, if you use access tokens then there are two clients involved in this flow.
We developing web application using MVC4 and Jquery Mobile. Recently we found one major issue which is "User using another account in same browser" so its overiding the existing account current browser. So we decided not to allow user to use two different account in one browser. We searched lot but unable to find perfect solution. So we tryed below code before login page load.
[AllowAnonymous]
public ActionResult Index()
{
if (!Request.IsAuthenticated)
{
return View("mLogin");
}
else
{
return View("UserAlready");
}
}
In login controller we written this code. The login page will be shown only when user is not registered. Once he Authenticated we restrict him from loading login page again.
My question.
Is this correct method ? Is it have any drawback? Or any other better approach is there?
Use a cookie with session id in it. In Authorize Action Filter check cookie for the session value with user session value if two match well and good otherwise you can take the necessary action
I have an MVC3 app and the user needs to be authenticated before they can access the site. I was logged in and was on a screen showing data, then i left. I came back an hour later, and by now the user has been automatically logged off. But when i clicked on a button to get data, without logging back in, I got the yellow screen of death cause my object was null. This is my Action:
[Authorize]
public ActionResult Index(string id)
I thought the [Authorize] attribute made sure to not execute this action unless they are authenticated, but apparently it doesnt or im not using it properly. So how do i use the [Authorize] or any other attribute to make sure the user is always authenticated and if they're not, take them to the login screen? Thanks
P.S. This only happens when a timeout has occurred. If i just try to access a view by typing in the URL and not logging in, i get the login screen as expected
I came back an hour later, and by now the user has been automatically logged off
If the action is executed, this means that the user is not logged off. The [Authorize] attribute works as expected.
I suspect that your problem has nothing to do with authentication. It has to do with ASP.NET Session that you are using. Please bear in mind that Forms Authentication cookie and ASP.NET Session are 2 completely different notions. So I guess that you have stored something into the ASP.NET Session when the user logged in. Except that the ASP.NET Session by default expires in 20 minutes and is configured independently of the forms authentication cookie timeout. So while the user authentication cookie is still valid and the user is authenticated it has lost its session because either the session expired or the web server simply recycled your application and everything you stored into the Session is of course lost.
This being said let's see the different possibilities that you have to workaround this problem:
My recommended approach is to get rid of the Session. Simply put <sessionState mode="Off" /> in your web.config and forget about the statefulness that the ASP.NET Session introduces in stateless applications.
Write a custom Authorize attribute which in addition to checking whether the authentication cookie is valid it will check if the Session still contains values:
public class MyAuthorizeAttribute : AuthorizeAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
var authorized = base.AuthorizeCore(httpContext);
if (!authorized)
{
return false;
}
return httpContext.Session["someKeyThatYouHaveStored"] != null;
}
}
and then use this custom attribute:
[MyAuthorize]
public ActionResult Index(string id)