private void SessionManager_ValidateSessionLessRequest(object sender, ValidateSessionLessRequestEventArgs e) { // check for encryption. var endpoint = SecureChannelContext.Current.EndpointDescription; if (endpoint == null || (endpoint.SecurityPolicyUri == SecurityPolicies.None && !endpoint.EndpointUrl.StartsWith(Uri.UriSchemeHttps)) || endpoint.SecurityMode == MessageSecurityMode.Sign) { e.Error = StatusCodes.BadSecurityModeInsufficient; return; } // find user token policy. JwtEndpointParameters parameters = null; foreach (var policy in endpoint.UserIdentityTokens) { if (policy.IssuedTokenType == "http://opcfoundation.org/UA/UserTokenPolicy#JWT") { parameters = new JwtEndpointParameters(); parameters.FromJson(policy.IssuerEndpointUrl); break; } } if (parameters == null) { e.Error = StatusCodes.BadIdentityTokenRejected; return; } // check authentication token. if (NodeId.IsNull(e.AuthenticationToken) || e.AuthenticationToken.IdType != IdType.String || e.AuthenticationToken.NamespaceIndex != 0) { e.Error = StatusCodes.BadIdentityTokenInvalid; return; } // validate token. string jwt = (string)e.AuthenticationToken.Identifier; var identity = ValidateJwt(parameters, jwt); Utils.Trace("JSON Web Token Accepted: {0}", identity.DisplayName); e.Identity = identity; e.Error = ServiceResult.Good; }
public static async Task <UserIdentity> GetIdentityToken(ApplicationConfiguration configuration, string endpointUrl) { // get an endpoint to use. var endpoint = ClientUtils.SelectEndpoint(endpointUrl, true); // find user token policy that supports JWTs. JwtEndpointParameters parameters = null; foreach (var policy in endpoint.UserIdentityTokens) { if (policy.IssuedTokenType == "http://opcfoundation.org/UA/UserTokenPolicy#JWT") { parameters = new JwtEndpointParameters(); parameters.FromJson(policy.IssuerEndpointUrl); break; } } if (parameters == null) { throw new ServiceResultException(StatusCodes.BadConfigurationError, "No JWT UserTokenPolicy specified for the selected GDS."); } // set the default resource. if (String.IsNullOrEmpty(parameters.ResourceId)) { parameters.ResourceId = endpoint.Server.ApplicationUri; } // get the authorization server that the GDS actually uses. var gdsCredentials = OAuth2CredentialCollection.FindByAuthorityUrl(configuration, parameters.AuthorityUrl); // create default credentials from the server endpoint. if (gdsCredentials == null) { gdsCredentials = new OAuth2Credential(); } // override with settings provided by server. gdsCredentials.AuthorityUrl = parameters.AuthorityUrl; gdsCredentials.GrantType = parameters.GrantType; gdsCredentials.TokenEndpoint = parameters.TokenEndpoint; JwtSecurityToken jwt = null; // need to get credentials from an external authority. if (gdsCredentials != null && gdsCredentials.GrantType == "site_token") { // need to find an OAuth2 server that can supply credentials. var azureCredentials = OAuth2CredentialCollection.FindByServerUri(configuration, parameters.ResourceId); if (azureCredentials == null) { throw new ServiceResultException(StatusCodes.BadConfigurationError, "No OAuth2 configuration specified for the selected GDS."); } // prompt user to provide credentials. var azureToken = new OAuth2CredentialsDialog().ShowDialog(azureCredentials); if (azureToken == null) { return(null); } jwt = new JwtSecurityToken(azureToken.AccessToken); IssuedIdentityToken issuedToken = new IssuedIdentityToken(); issuedToken.IssuedTokenType = IssuedTokenType.JWT; issuedToken.DecryptedTokenData = new UTF8Encoding(false).GetBytes(jwt.RawData); var azureIdentity = new UserIdentity(issuedToken); // log in using site token. OAuth2Client client = new OAuth2Client() { Configuration = configuration }; var certificate = await client.Configuration.SecurityConfiguration.ApplicationCertificate.Find(true); var gdsAccessToken = await client.RequestTokenWithWithSiteTokenAsync(gdsCredentials, certificate, azureToken.AccessToken, parameters.ResourceId, "gdsadmin"); JwtSecurityToken gdsToken = new JwtSecurityToken(gdsAccessToken.AccessToken); issuedToken = new IssuedIdentityToken(); issuedToken.IssuedTokenType = IssuedTokenType.JWT; issuedToken.DecryptedTokenData = new UTF8Encoding(false).GetBytes(gdsToken.RawData); return(new UserIdentity(issuedToken)); } // attempt to log in directly else { string username = null; string password = null; // TBD - Prompt User to Provide. OAuth2Client client = new OAuth2Client() { Configuration = configuration }; var gdsAccessToken = await client.RequestTokenWithWithUserNameAsync(gdsCredentials, username, password, parameters.ResourceId, "gdsadmin"); JwtSecurityToken gdsToken = new JwtSecurityToken(gdsAccessToken.AccessToken); IssuedIdentityToken issuedToken = new IssuedIdentityToken(); issuedToken.IssuedTokenType = IssuedTokenType.JWT; issuedToken.DecryptedTokenData = new UTF8Encoding(false).GetBytes(gdsToken.RawData); return(new UserIdentity(issuedToken)); } }
/// <summary> /// Called when a client tries to change its user identity. /// </summary> private void SessionManager_ImpersonateUser(Session session, ImpersonateEventArgs args) { // check for an issued token. IssuedIdentityToken issuedToken = args.NewIdentity as IssuedIdentityToken; if (issuedToken != null) { if (args.UserTokenPolicy.IssuedTokenType == "http://opcfoundation.org/UA/UserTokenPolicy#JWT") { JwtEndpointParameters parameters = new JwtEndpointParameters(); parameters.FromJson(args.UserTokenPolicy.IssuerEndpointUrl); var jwt = new UTF8Encoding().GetString(issuedToken.DecryptedTokenData); var identity = ValidateJwt(parameters, jwt); Utils.Trace("JSON Web Token Accepted: {0}", identity.DisplayName); args.Identity = identity; return; } } // check for a user name token. UserNameIdentityToken userNameToken = args.NewIdentity as UserNameIdentityToken; if (userNameToken != null) { var identity = new UserIdentity(userNameToken); var token = (UserNameIdentityToken)identity.GetIdentityToken(); switch (token.UserName) { case "gdsadmin": { if (token.DecryptedPassword == "demo") { Utils.Trace("GdsAdmin Token Accepted: {0}", args.Identity.DisplayName); return; } break; } case "appadmin": { if (token.DecryptedPassword == "demo") { args.Identity = new RoleBasedIdentity(identity, GdsRole.ApplicationAdmin); Utils.Trace("ApplicationAdmin Token Accepted: {0}", args.Identity.DisplayName); return; } break; } case "appuser": { if (token.DecryptedPassword == "demo") { args.Identity = new RoleBasedIdentity(identity, GdsRole.ApplicationUser); Utils.Trace("ApplicationUser Token Accepted: {0}", args.Identity.DisplayName); return; } break; } } args.Identity = identity; Utils.Trace("UserName Token Accepted: {0}", args.Identity.DisplayName); return; } // check for x509 user token. X509IdentityToken x509Token = args.NewIdentity as X509IdentityToken; if (x509Token != null) { VerifyCertificate(x509Token.Certificate); args.Identity = new UserIdentity(x509Token); Utils.Trace("X509 Token Accepted: {0}", args.Identity.DisplayName); return; } }