I'm trying to use use AuthorizeRequest and AuthorizeResponse inside an MVC action to see if the user is already authenticated, but pretty much everything in the response object comes back null besides Raw, Scope, and State. IsError is false.
I have an Application A and an Application B. I want to know in Application A if the user already signed in for Application B.
var request = new AuthorizeRequest("https://localhost:5000/connect/authorize");
var url = request.CreateAuthorizeUrl(
clientId: "Portal-Local",
scope: "openid profile email",
responseType: OidcConstants.ResponseTypes.IdToken,
responseMode: OidcConstants.ResponseModes.FormPost,
redirectUri: "https://localhost/Portal/home/index",
state: CryptoRandom.CreateUniqueId(),
nonce: CryptoRandom.CreateUniqueId());
var response = new AuthorizeResponse(url);
var accessToken = response.AccessToken;
var idToken = response.IdentityToken;
var state = response.State;
Related
I would like to load data from VEEML to our website. I found some documentation on the API /getgrid2 but I need to add my security token in the query.
How can I get my security token? Is there a specific endpoint that I can call?
Each time you will use a VEEML API, you need to be authenticated properly by the method /login.
Using this endpoint, you will get a valid authentication token to use with the other endpoints.
You need to include the javascript library sah256.js previously.
-> "https://the-url.ofyour.portal/js/sah256.js"
var _email = 'myemail; // Here the email of an "admin" account
var _password = 'mypassword'; // Here the password
var _hash = CryptoJS.SHA256(_password);
var _data = {"email": _email, "password": _hash.toString()};
var _url = "https://the-url.ofyour.portal/login"; //
api to authenticate the user
$.ajax({
type: "POST",
url: _url,
dataType : 'jsonp',
data: _data,
error: function(xhr, response, error)
{console.log(error);},
success: function(json){console.log(json.success);
});
I'm using the below guide to setup Oauth2 for my app.
https://learn.microsoft.com/en-us/graph/auth-v2-user
this is the /authorize URL get request, which is working fine:
GET https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=${clientId}&response_type=code&redirect_uri=${redirectUri}&response_mode=query&scope=offline_access%20user.read%20files.readwrite
then, i get the code from the redirectUri and POST to this URL:
POST https://login.microsoftonline.com/common/oauth2/v2.0/token
Which returns a access_token and a refresh_token.
However, whenever i need to refresh the tokens, Graph API only returns a new access_token.
I'm using axios and qs:
//get new tokens
const scope = "Files.ReadWrite";
const data = qs.stringify({
client_id: clientId,
client_secret: clientSecret,
grant_type: "refresh_token",
redirect_uri: redirectUri,
scope: scope,
refresh_token: oneDriveRefreshToken
});
const headers = {
"Content-Type": "application/x-www-form-urlencoded",
};
const response = await axios.post(tokenEndpoint, data, headers);
const json = response.data;
functions.logger.debug(json.access_token); //ok
functions.logger.debug(json.refresh_token); //undefined
As far as i understand, the authorization code flow along with "offline_access" scope should enable you to get a new refresh token when calling the /token endpoint
I noticed that the scope you defined in the code does not include offline_access, so it just returns you an access token with Files.ReadWrite permission. If you want to obtain an refresh token, please add offline_access to the scope.
Try to change the scope to: const scope = "Files.ReadWrite offline_access";.
Hi I am using IdentityServer4 with aspnet core application.
I am using MVC client from their sample and also using a javascript client. The javascript client can be opened as tenantone.domain.com or tenanttwo.domain.com and so on according to tenancy name.
I am not able to get authorization for dynamic sub-domains.
Please help! if any one has done such task in asp.net core
To Register the javascript client I am using below code
string tenancyName = "tenantone"
var discoveryClient = new DiscoveryClient("http://login.domain.io:5000");
discoveryClient.Policy.RequireHttps = false;
var doc = await discoveryClient.GetAsync();
var request = new IdentityModel.Client.AuthorizeRequest(doc.AuthorizeEndpoint);
var url = new IdentityModel.Client.AuthorizeRequest(doc.AuthorizeEndpoint).CreateAuthorizeUrl(
clientId: tenancyName,
responseType: ResponseTypes.IdTokenToken,
scope: "openid profile api1",
redirectUri: "http://" + tenancyName + ".domain.io:5003/callback.html",
state: "random_state",
nonce: "random_nonce",
responseMode: "form_post",
extra: new
{
AllowedCorsOrigins = "http://" + tenancyName + ".domain.io:5003"
});
var response = new IdentityModel.Client.AuthorizeResponse(url);
var accessToken = response.AccessToken;
var idToken = response.IdentityToken;
var state = response.State;
Then after to be authorized from client I am using below code:
var config = {
authority: "http://login.domain.io:5000",
client_id: "tenantone",
redirect_uri: "http://tenantone.domain.io:5003/callback.html",
response_type: "id_token token",
scope: "openid profile api1",
post_logout_redirect_uri: "http://tenantone.domain.io:5003/",
};
var mgr = new Oidc.UserManager(config);
debugger;
mgr.getUser().then(function (user) {
if (user) {
//log("User logged in", user.profile);
$("#bodyPage").removeAttr("style");
}
else {
// log("User not logged in");
mgr.signinRedirect();
}
});
I've downloaded the JWT version of the oauth2 server (https://github.com/spring-guides/tut-spring-security-and-angular-js/tree/master/oauth2) and I've been trying to replace the default login form to another using angularjs.
That I made was:
Create a request mapping for the new login form
`
#RequestMapping(value = {"/login"})
public String redirect(#RequestParam(required = false) String code, #RequestParam(required = false) String state) {
return "redirect:/#/login";
}
`
Call to the login endpoint using $http.post (XSRF-TOKEN has been injected with an interceptor):
`
var params = {username: credentials.username, password: credentials.password};
var config = {
headers: {'content-type': 'application/x-www-form-urlencoded; charset=utf-8'}
};
CoreService.httpPost('login', $httpParamSerializer(params), config)
.then( function(data) {...});
`
All looks ok, Angular send the information, the client info is obtained from our BD, the user is searched in our Data Base or LDAP. When the user is founded and the login process finish ok, the symtem redirect to the zuul server, but the jsessionid it's not present, so the Zuul server can't validate the token.
However, If I refresh the IU page, the token validation works perfectly
So, could you tell me what I have to do or what I'm doing wrong?
Thanks a lot
I'm building a SPA using Angular.js and ASP.NET and I would like to know what is the best way to secure it.
Here is what I need :
I would like to use MVC framework to hide my application only to logged users. So the first thing that users will do before launching the SPA will be to log into the website using a simple login form.
When the Angular app will be launched, it will communicate with my ApiController using REST requests.
I also want my user to be logged out automatically after 20 minutes of inactivity.
I know that REST is supposed to be stateless... but I can't figure how to implement all I need without sessions...
But on the other side, I want to be able to use my WebAPI with a future mobile application. I will have to use Tokens for the authentication on this application.
What is the best way for me to achieve that kind of authentication?
Thanks for your time!
I developed an entire security layer with the same conditions as yours following those very well explained in this post here.
BTW, the token will expire automatically after 20 minutes because when you create it you will set it's expiration date immediately; every time you're going to make a request, the system will check the token exp date with the current date, refusing your token if the time passed. For example this a tipical oauth server configuration with token and refresh token settings:
internal static OAuthAuthorizationServerOptions GetAuthorizationServerOptions(IComponentContext scope)
{
OAuthAuthorizationServerOptions oAuthServerOptions = new OAuthAuthorizationServerOptions
{
AllowInsecureHttp = true,
ApplicationCanDisplayErrors = true,
TokenEndpointPath = new PathString(Constants.PublicAuth.OAUTH_TOKEN_PATH),
AuthorizeEndpointPath = new PathString(Constants.ExternalAuth.AUTH_ENDPOINT),
AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(Constants.PublicAuth.TOKEN_EXPIRATION_IN_MINUTES),
Provider = scope.Resolve<AuthorizationServerProvider>(),
AccessTokenFormat = new CustomJwtFormat(),
RefreshTokenProvider = scope.Resolve<SimpleRefreshTokenProvider>()
};
return oAuthServerOptions;
}
The refresh token is also very useful, but you have to manage the token replacement by yourself; for example in our application we pass every API call through a single service that, if the server responds 401 (unauthorized), it will try to request a new token using the refresh token and then it will try the same call again. Only after the second failure you'll be redirected to the login page.
For example:
function executeCallWithAuth(method, url, payload, params) {
var defer = $q.defer();
debug.logf('{0}: {1}', method.toUpperCase(), url);
$http({ method: method, url: url, data: payload, headers: createHeaders(), params: params }).then(
function(results) { defer.resolve(results); },
function(error) {
if (error.status !== 401) defer.reject(error);
else {
debug.warn(`Call to: ${method}:${url} result in 401, try token refresh...`);
auth.refreshToken().then(
function() {
debug.warn('Token refresh succesfully, retry api call...');
$http({ method: method, url: url, data: payload, headers: createHeaders() }).then(
function(results) { defer.resolve(results); },
function(errors) { defer.reject(errors); });
},
function(tokenError) {
debug.warn('Token refresh rejected, redirect to login.');
$state.go('login');
defer.reject(tokenError);
});
}
});
return defer.promise;
}
and
function createHeaders() {
var headers = {
};
var authData = storage.get('authorizationData');
if (authData) {
headers.Authorization = 'Bearer ' + authData.token;
}
return headers;
}
Using Angular the best way to secure a route is "do not create a route". Basically, you need to load the user profile, and only after that you will create the routes only to the pages he can navigate to. If you don't create the route for a page you don't need to secure that page: Angular will automatically send the user to a 404.
I would secure your WebAPI calls with OAuth2 (you can even use the built in Identity 2.0 provider that comes baked in with it). Keep your WebAPI stateless, use SSL (consider a filter to force it), and use the [Authorize] tags to secure you services. On the MVC side, this will have to maintain state and you will want to have the login form get an OAuth2 token from your WebAPI layer and pass that down into Angular. Set the expiration on this to 20 minutes. You can also use the cookies authentication model here since it will need to be stateful on the MVC side, but all ajax calls made to the WebAPI layer by Angular will need to pass the OAuth2 token as a bearer token in the Authorization request header.