I'm using owin for my app, Web Api2 for working with data and MVC5 for view.
static Startup()
{
PublicClientId = "self";
UserManagerFactory = () => new UserManager<User, int>(new UserRepository());
OAuthOptions = new OAuthAuthorizationServerOptions
{
TokenEndpointPath = new PathString("/Account/Token"),
AuthorizeEndpointPath = new PathString("/Account/ExternalLogin"),
Provider = new ApplicationOAuthProvider(PublicClientId, UserManagerFactory),
RefreshTokenProvider = new SimpleRefreshTokenProvider(),
AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(59),
AllowInsecureHttp = true,
};
}
When user is logged in through /Token?username=x&password=x&grant_type=password, it generates bearer token with refresh GUID for future refresh token /Token?grant_type=refresh_token, all is working okey.
My app can login through Facebook, etc, it's getting data I need from Facebook (email, etc) then I want to generate token with refresh GUID, problem is that for refreshing I need to pass data through /Token?username&password but my user doesn't have password, I tough to send additional parameter Scope and show what provider and provider key its using and to search in DB this user is registered and give him permission to generate token.
Is this good idea?

I found solution, without using garnt_type=password:
This is my refresh token class that AuthroizationServer is using
public class SimpleRefreshTokenProvider : IAuthenticationTokenProvider
{
private static ConcurrentDictionary<string, AuthenticationTicket> _refreshTokens =
new ConcurrentDictionary<string, AuthenticationTicket>();
public async Task CreateAsync(AuthenticationTokenCreateContext context)
{.......}
public async Task ReceiveAsync(AuthenticationTokenReceiveContext context)
{.......}
}
My AccountController is initialized like this:
public AccountController()
: this(Startup.UserManagerFactory(), Startup.OAuthOptions.AccessTokenFormat)
{
}
public AccountController(UserManager<User, int> userManager, ISecureDataFormat<AuthenticationTicket> accessTokenFormat)
{
UserManager = userManager;
AccessTokenFormat = accessTokenFormat;
UserManager.UserValidator = new CustomUserValidator<User>(UserManager);
}
Now I need to create AuthenticationTokenCreateContext and send it to my RefreshTokenProvider so it will add Refresh Guid in _refreshTokens, so when I will send my refreshGuid it will be valid. Where I'm creating Identity for ExternalUser
ClaimsIdentity oAuthIdentity = await UserManager.CreateIdentityAsync(user,
OAuthDefaults.AuthenticationType);
AuthenticationProperties properties = ApplicationOAuthProvider.CreateProperties(user.Id.ToString());
oAuthIdentity.AddClaim(new Claim("TokenGuid", Guid.NewGuid().ToString()));
var ticket = new AuthenticationTicket(oAuthIdentity, properties);
await Startup.OAuthOptions.RefreshTokenProvider.CreateAsync(new AuthenticationTokenCreateContext(Request.GetOwinContext(), AccessTokenFormat, ticket));
Authentication.SignIn(properties, oAuthIdentity);
Now all my tokens can be refreshed, because I passed TokenGuid to RefreshTokenProvider, after that I'm creating token with that GUID and next time I will refresh it /Token?grant_type=refresh_token.....
P.S. If you need detailed help you can write me.
A few extra remarks:
Startup.OAuthOptions.RefreshTokenFormat
instead of Startup.OAuthOptions.AccessTokenFormat
public override Task AuthorizationEndpointResponse(OAuthAuthorizationEndpointResponseContext context)
{
var refreshToken = context.OwinContext.Authentication.AuthenticationResponseGrant.Properties.Dictionary["refresh_token"];
if (!string.IsNullOrEmpty(refreshToken))
{
context.AdditionalResponseParameters.Add("refresh_token", refreshToken);
}
return base.AuthorizationEndpointResponse(context);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With