/// <summary> /// Initializes a new instance of the MobileConnectWebInterface class /// </summary> /// <param name="discovery">Instance of IDiscovery concrete implementation</param> /// <param name="authentication">Instance of IAuthentication concrete implementation</param> /// <param name="config">Configuration options</param> public MobileConnectWebInterface(IDiscovery discovery, IAuthentication authentication, MobileConnectConfig config) { this._discovery = discovery; this._authentication = authentication; this._config = config; this._cacheWithSessionId = config.CacheResponsesWithSessionId && discovery.Cache != null; }
/// <summary> /// Initializes a new instance of the MobileConnectWebInterface class using default concrete implementations /// </summary> /// <param name="config">Configuration options</param> /// <param name="cache">Concrete implementation of ICache</param> /// <param name="client">Restclient for all http requests. Will default if null.</param> public MobileConnectWebInterface( MobileConnectConfig config, ICache cache, RestClient client, ICache discoveryCache) : this(new DiscoveryService(discoveryCache, client), new AuthenticationService(client), new IdentityService(client), new JWKeysetService(client, cache), config) { }
/// <summary> /// Initializes a new instance of the MobileConnectInterface class /// </summary> /// <param name="config">Configuration options</param> /// <param name="discovery">Instance of IDiscovery concrete implementation</param> /// <param name="authentication">Instance of IAuthentication concrete implementation</param> /// <param name="identity">Instance of IIdentityService concrete implementation</param> /// <param name="jwks">Instance of IJWKeysetService concrete implementation</param> public MobileConnectInterface(MobileConnectConfig config, IDiscoveryService discovery, IAuthenticationService authentication, IIdentityService identity, IJWKeysetService jwks) { this._discovery = discovery; this._authentication = authentication; this._identity = identity; this._jwks = jwks; this._config = config; }
public MobileConnectInterface(IDiscoveryService discovery, IAuthenticationService authentication, MobileConnectConfig config) { var client = new RestClient(); _discovery = discovery; _authentication = authentication; _identity = new IdentityService(client); _jwks = new JWKeysetService(client, new DiscoveryCache()); _config = config; }
public MobileConnectInterface(IDiscoveryService discovery, IAuthenticationService authentication, MobileConnectConfig config) { var cache = discovery.Cache; var client = new Utils.RestClient(); this._discovery = discovery; this._authentication = authentication; this._identity = new IdentityService(client); this._jwks = new JWKeysetService(client, cache); this._config = config; }
/// <summary> /// Initializes a new instance of the MobileConnectWebInterface class /// </summary> /// <param name="discovery">Instance of IDiscovery concrete implementation</param> /// <param name="authentication">Instance of IAuthentication concrete implementation</param> /// <param name="identity">Instance of IIdentityService concrete implementation</param> /// <param name="jwks">Instance of IJWKeysetService concrete implementation</param> /// <param name="config">Configuration options</param> public MobileConnectWebInterface(IDiscoveryService discovery, IAuthenticationService authentication, IIdentityService identity, IJWKeysetService jwks, MobileConnectConfig config) { this._discovery = discovery; this._authentication = authentication; this._identity = identity; this._jwks = jwks; this._config = config; this._cacheWithSessionId = config.CacheResponsesWithSessionId && discovery.Cache != null; Log.Debug(() => _cacheWithSessionId ? $"MobileConnectWebInterface caching enabled with type={discovery.Cache.GetType().AssemblyQualifiedName}" : "MobileConnectWebInterface caching disabled"); }
public MobileConnectWebInterface(IDiscoveryService discovery, IAuthenticationService authentication, MobileConnectConfig config) { var cache = discovery.Cache; var client = new Utils.RestClient(); this._discovery = discovery; this._authentication = authentication; this._identity = new IdentityService(client); this._jwks = new JWKeysetService(client, cache); this._config = config; this._cacheWithSessionId = config.CacheResponsesWithSessionId && _discovery.Cache != null; Log.Debug(() => _cacheWithSessionId ? $"MobileConnectWebInterface caching enabled with type={cache.GetType().AssemblyQualifiedName}" : "MobileConnectWebInterface caching disabled"); }
internal static async Task <MobileConnectStatus> AttemptDiscovery( IDiscoveryService discovery, string msisdn, string mcc, string mnc, IEnumerable <BasicKeyValuePair> cookies, MobileConnectConfig config, MobileConnectRequestOptions options) { DiscoveryResponse response = null; try { DiscoveryOptions discoveryOptions = options?.DiscoveryOptions ?? new DiscoveryOptions(); discoveryOptions.MSISDN = msisdn; discoveryOptions.IdentifiedMCC = mcc; discoveryOptions.IdentifiedMNC = mnc; discoveryOptions.RedirectUrl = config.RedirectUrl; discoveryOptions.XRedirect = config.XRedirect; response = await discovery.StartAutomatedOperatorDiscoveryAsync( config, config.RedirectUrl, discoveryOptions, cookies); } catch (MobileConnectInvalidArgumentException e) { Log.Error(() => $"An invalid argument was passed to AttemptDiscovery arg={e.Argument}"); return(MobileConnectStatus.Error(ErrorCodes.InvalidArgument, string.Format("An argument was found to be invalid during the process. The argument was {0}.", e.Argument), e)); } catch (MobileConnectEndpointHttpException e) { Log.Error(() => $"A general http error occurred in AttemptDiscovery msisdn={!string.IsNullOrEmpty(msisdn)} mcc={mcc} mnc={mnc} discoveryUrl={config.DiscoveryUrl}"); return(MobileConnectStatus.Error(ErrorCodes.HttpFailure, "An HTTP failure occured while calling the discovery endpoint, the endpoint may be inaccessible", e)); } catch (Exception e) { Log.Error(() => $"A general error occurred in AttemptDiscovery msisdn={!string.IsNullOrEmpty(msisdn)} mcc={mcc} mnc={mnc} discoveryUrl={config.DiscoveryUrl}"); return(MobileConnectStatus.Error(ErrorCodes.Unknown, "An unknown error occured while calling the Discovery service to obtain operator details", e)); } return(GenerateStatusFromDiscoveryResponse(discovery, response)); }
public MobileConnectWebInterface( IDiscoveryService discovery, IAuthenticationService authentication, MobileConnectConfig config) { var client = new RestClient(); _discovery = discovery; _authentication = authentication; _identity = new IdentityService(client); _jwks = new JWKeysetService(client, new DiscoveryCache()); _config = config; _cacheWithSessionId = config.CacheResponsesWithSessionId; _sessionCahce = new SessionCache(); Log.Debug(() => _cacheWithSessionId ? $"MobileConnectWebInterface caching enabled with " + $"type={_sessionCahce.GetType().AssemblyQualifiedName}" : "MobileConnectWebInterface caching disabled"); }
internal static async Task <MobileConnectStatus> RevokeToken(IAuthenticationService authentication, string token, string tokenTypeHint, DiscoveryResponse discoveryResponse, MobileConnectConfig config) { Validate.RejectNull(discoveryResponse, "discoveryResponse"); Validate.RejectNullOrEmpty(token, "token"); string revokeTokenUrl = discoveryResponse.OperatorUrls.RevokeTokenUrl; var notSupported = IsSupported(revokeTokenUrl, "Revoke", discoveryResponse.ProviderMetadata?.Issuer); if (notSupported != null) { return(notSupported); } string clientId = discoveryResponse.ResponseData.response.client_id; string clientSecret = discoveryResponse.ResponseData.response.client_secret; try { var response = await authentication.RevokeTokenAsync(clientId, clientSecret, revokeTokenUrl, token, tokenTypeHint); return(MobileConnectStatus.TokenRevoked(response)); } catch (Exception e) { Log.Error(() => $"RevokeToken failed", e); return(MobileConnectStatus.Error(ErrorCodes.Unknown, "Revoke token error", e)); } }
internal static async Task <MobileConnectStatus> RefreshToken(IAuthenticationService authentication, string refreshToken, DiscoveryResponse discoveryResponse, MobileConnectConfig config) { Validate.RejectNull(discoveryResponse, "discoveryResponse"); Validate.RejectNullOrEmpty(refreshToken, "refreshToken"); if (!IsUsableDiscoveryResponse(discoveryResponse)) { return(MobileConnectStatus.StartDiscovery()); } string refreshTokenUrl = discoveryResponse.OperatorUrls.RefreshTokenUrl ?? discoveryResponse.OperatorUrls.RequestTokenUrl; var notSupported = IsSupported(refreshTokenUrl, "Refresh", discoveryResponse.ProviderMetadata?.Issuer); if (notSupported != null) { return(notSupported); } string clientId = discoveryResponse.ResponseData.response.client_id ?? config.ClientId; string clientSecret = discoveryResponse.ResponseData.response.client_secret ?? config.ClientSecret; try { RequestTokenResponse requestTokenResponse = await authentication.RefreshTokenAsync(clientId, clientSecret, refreshTokenUrl, refreshToken); ErrorResponse errorResponse = requestTokenResponse.ErrorResponse; if (errorResponse != null) { Log.Error(() => $"Responding with responseType={MobileConnectResponseType.Error} for refreshToken for authentication service responded with error={errorResponse.Error}"); return(MobileConnectStatus.Error(errorResponse)); } else { Log.Info(() => $"Refresh token success"); return(MobileConnectStatus.Complete(requestTokenResponse)); } } catch (Exception e) { Log.Error(() => $"RefreshToken failed", e); return(MobileConnectStatus.Error(ErrorCodes.Unknown, "Refresh token error", e)); } }
internal static async Task <MobileConnectStatus> RequestIdentity(IIdentityService _identity, DiscoveryResponse discoveryResponse, string accessToken, MobileConnectConfig _config, MobileConnectRequestOptions options) { string identityUrl = discoveryResponse?.OperatorUrls?.PremiumInfoUrl; var notSupported = IsSupported(identityUrl, "Identity", discoveryResponse?.ProviderMetadata?.Issuer); if (notSupported != null) { return(notSupported); } try { var response = await _identity.RequestIdentity(identityUrl, accessToken); return(MobileConnectStatus.Identity(response)); } catch (MobileConnectInvalidArgumentException e) { Log.Error(() => $"An invalid argument was passed to RequestIdentity arg={e.Argument}"); return(MobileConnectStatus.Error(ErrorCodes.InvalidArgument, string.Format("An argument was found to be invalid during the process. The argument was {0}.", e.Argument), e)); } catch (MobileConnectEndpointHttpException e) { Log.Error(() => $"A general http error occurred in RequestUserInfo identityUrl={identityUrl}"); return(MobileConnectStatus.Error(ErrorCodes.HttpFailure, "An HTTP failure occured while calling the operator token endpoint, the endpoint may be inaccessible", e)); } catch (Exception e) { Log.Error(() => $"A general error occurred in RequestUserInfo identityUrl={identityUrl}"); return(MobileConnectStatus.Error(ErrorCodes.Unknown, "A failure occured while requesting a token", e)); } }
internal static async Task <MobileConnectStatus> AttemptDiscoveryAfterOperatorSelection(IDiscovery discovery, Uri redirectedUrl, MobileConnectConfig config) { var parsedRedirect = discovery.ParseDiscoveryRedirect(redirectedUrl); if (!parsedRedirect.HasMCCAndMNC) { return(MobileConnectStatus.StartDiscovery()); } DiscoveryResponse response; try { response = await discovery.CompleteSelectedOperatorDiscoveryAsync(config, config.RedirectUrl, parsedRedirect.SelectedMCC, parsedRedirect.SelectedMNC); if (response.ResponseData?.subscriber_id == null) { response.ResponseData.subscriber_id = parsedRedirect.EncryptedMSISDN; } } catch (MobileConnectInvalidArgumentException e) { return(MobileConnectStatus.Error("invalid_argument", string.Format("An argument was found to be invalid during the process. The argument was {0}.", e.Argument), e)); } catch (MobileConnectEndpointHttpException e) { return(MobileConnectStatus.Error("http_failure", "An HTTP failure occured while calling the discovery endpoint, the endpoint may be inaccessible", e)); } catch (Exception e) { return(MobileConnectStatus.Error("unknown_error", "An unknown error occured while calling the Discovery service to obtain operator details", e)); } return(GenerateStatusFromDiscoveryResponse(discovery, response)); }
internal static async Task <MobileConnectStatus> AttemptDiscovery(IDiscovery discovery, string msisdn, string mcc, string mnc, IEnumerable <BasicKeyValuePair> cookies, MobileConnectConfig config, MobileConnectRequestOptions options) { DiscoveryResponse response = null; try { DiscoveryOptions discoveryOptions = options?.DiscoveryOptions ?? new DiscoveryOptions(); discoveryOptions.MSISDN = msisdn; discoveryOptions.IdentifiedMCC = mcc; discoveryOptions.IdentifiedMNC = mnc; discoveryOptions.RedirectUrl = config.RedirectUrl; response = await discovery.StartAutomatedOperatorDiscoveryAsync(config, config.RedirectUrl, discoveryOptions, cookies); } catch (MobileConnectInvalidArgumentException e) { return(MobileConnectStatus.Error("invalid_argument", string.Format("An argument was found to be invalid during the process. The argument was {0}.", e.Argument), e)); } catch (MobileConnectEndpointHttpException e) { return(MobileConnectStatus.Error("http_failure", "An HTTP failure occured while calling the discovery endpoint, the endpoint may be inaccessible", e)); } catch (Exception e) { return(MobileConnectStatus.Error("unknown_error", "An unknown error occured while calling the Discovery service to obtain operator details", e)); } return(GenerateStatusFromDiscoveryResponse(discovery, response)); }
/// <summary> /// Initializes a new instance of the MobileConnectWebInterface class using default concrete implementations /// </summary> /// <param name="config">Configuration options</param> /// <param name="cache">Concrete implementation of ICache</param> public MobileConnectWebInterface(MobileConnectConfig config, ICache cache, ICache discoveryCache) : this(config, cache, new RestClient(), discoveryCache) { }
internal static MobileConnectStatus StartAuthentication(IAuthenticationService authentication, DiscoveryResponse discoveryResponse, string encryptedMSISDN, string state, string nonce, MobileConnectConfig config, MobileConnectRequestOptions options) { if (!IsUsableDiscoveryResponse(discoveryResponse)) { return(MobileConnectStatus.StartDiscovery()); } StartAuthenticationResponse response; try { string clientId = discoveryResponse.ResponseData.response.client_id ?? config.ClientId; string authorizationUrl = discoveryResponse.OperatorUrls.AuthorizationUrl; SupportedVersions supportedVersions = discoveryResponse.ProviderMetadata?.MobileConnectVersionSupported; AuthenticationOptions authOptions = options?.AuthenticationOptions ?? new AuthenticationOptions(); authOptions.ClientName = discoveryResponse.ApplicationShortName; response = authentication.StartAuthentication(clientId, authorizationUrl, config.RedirectUrl, state, nonce, encryptedMSISDN, supportedVersions, authOptions); } catch (MobileConnectInvalidArgumentException e) { Log.Error(() => $"An invalid argument was passed to StartAuthentication arg={e.Argument}"); return(MobileConnectStatus.Error(ErrorCodes.InvalidArgument, string.Format("An argument was found to be invalid during the process. The argument was {0}.", e.Argument), e)); } catch (Exception e) { Log.Error(() => $"A general error occurred in AttemptDiscoveryAfterOperatorSelection state={state} nonce={nonce} authUrl={discoveryResponse.OperatorUrls.AuthorizationUrl}"); return(MobileConnectStatus.Error(ErrorCodes.Unknown, "An unknown error occured while generating an authorization url", e)); } return(MobileConnectStatus.Authentication(response.Url, state, nonce)); }
/// <summary> /// Initializes a new instance of the MobileConnectInterface class using default concrete implementations /// </summary> /// <param name="config">Configuration options</param> /// <param name="cache">Concrete implementation of ICache</param> public MobileConnectInterface(MobileConnectConfig config, ICache cache) : this(config, cache, new RestClient()) { }
internal static async Task <MobileConnectStatus> RequestHeadlessAuthentication(IAuthenticationService authentication, IJWKeysetService jwks, IIdentityService identity, DiscoveryResponse discoveryResponse, string encryptedMSISDN, string state, string nonce, MobileConnectConfig config, MobileConnectRequestOptions options, CancellationToken cancellationToken = default(CancellationToken)) { if (!IsUsableDiscoveryResponse(discoveryResponse)) { return(MobileConnectStatus.StartDiscovery()); } MobileConnectStatus status; try { string clientId = discoveryResponse.ResponseData.response.client_id ?? config.ClientId; string clientSecret = discoveryResponse.ResponseData.response.client_secret; string authorizationUrl = discoveryResponse.OperatorUrls.AuthorizationUrl; string tokenUrl = discoveryResponse.OperatorUrls.RequestTokenUrl; string issuer = discoveryResponse.ProviderMetadata.Issuer; SupportedVersions supportedVersions = discoveryResponse.ProviderMetadata.MobileConnectVersionSupported; AuthenticationOptions authOptions = options?.AuthenticationOptions ?? new AuthenticationOptions(); authOptions.ClientName = discoveryResponse.ApplicationShortName; var jwksTask = jwks.RetrieveJWKSAsync(discoveryResponse.OperatorUrls.JWKSUrl); var tokenTask = authentication.RequestHeadlessAuthentication(clientId, clientSecret, authorizationUrl, tokenUrl, config.RedirectUrl, state, nonce, encryptedMSISDN, supportedVersions, authOptions, cancellationToken); // execute both tasks in parallel await Task.WhenAll(tokenTask, jwksTask).ConfigureAwait(false); RequestTokenResponse response = tokenTask.Result; status = HandleTokenResponse(authentication, response, clientId, issuer, nonce, discoveryResponse.ProviderMetadata.MobileConnectVersionSupported.MaxSupportedVersionString, jwksTask.Result, options); } catch (MobileConnectInvalidArgumentException e) { Log.Error(() => $"An invalid argument was passed to RequestHeadlessAuthentication arg={e.Argument}"); return(MobileConnectStatus.Error(ErrorCodes.InvalidArgument, string.Format("An argument was found to be invalid during the process. The argument was {0}.", e.Argument), e)); } catch (MobileConnectEndpointHttpException e) { Log.Error(() => $"A general http error occurred in RequestHeadlessAuthentication state={state} nonce={nonce} authUrl={discoveryResponse.OperatorUrls.AuthorizationUrl} tokenUrl={discoveryResponse.OperatorUrls.RequestTokenUrl}"); return(MobileConnectStatus.Error(ErrorCodes.HttpFailure, "An HTTP failure occured while calling the discovery endpoint, the endpoint may be inaccessible", e)); } catch (Exception e) { Log.Error(() => $"A general error occurred in RequestHeadlessAuthentication state={state} nonce={nonce} authUrl={discoveryResponse.OperatorUrls.AuthorizationUrl} tokenUrl={discoveryResponse.OperatorUrls.RequestTokenUrl}"); return(MobileConnectStatus.Error(ErrorCodes.Unknown, "An unknown error occured while generating an authorization url", e)); } if (status.ResponseType == MobileConnectResponseType.Error || !options.AutoRetrieveIdentityHeadless || string.IsNullOrEmpty(discoveryResponse.OperatorUrls.PremiumInfoUrl)) { return(status); } var identityStatus = await RequestIdentity(identity, discoveryResponse, status.TokenResponse.ResponseData.AccessToken, config, options); status.IdentityResponse = identityStatus.IdentityResponse; return(status); }
internal static async Task <MobileConnectStatus> RequestToken(IAuthentication authentication, DiscoveryResponse discoveryResponse, Uri redirectedUrl, string expectedState, string expectedNonce, MobileConnectConfig config) { RequestTokenResponse response; if (string.IsNullOrEmpty(expectedState)) { return(MobileConnectStatus.Error("required_arg_missing", "ExpectedState argument was not supplied, this is needed to prevent Cross-Site Request Forgery", null)); } if (string.IsNullOrEmpty(expectedNonce)) { return(MobileConnectStatus.Error("required_arg_missing", "expectedNonce argument was not supplied, this is needed to prevent Replay Attacks", null)); } var actualState = HttpUtils.ExtractQueryValue(redirectedUrl.Query, "state"); if (expectedState != actualState) { return(MobileConnectStatus.Error("invalid_state", "State values do not match, this could suggest an attempted Cross-Site Request Forgery", null)); } try { var code = HttpUtils.ExtractQueryValue(redirectedUrl.Query, "code"); var clientId = discoveryResponse?.ResponseData?.response?.client_id ?? config.ClientId; var clientSecret = discoveryResponse?.ResponseData?.response?.client_secret ?? config.ClientSecret; var requestTokenUrl = discoveryResponse?.OperatorUrls?.RequestTokenUrl; response = await authentication.RequestTokenAsync(clientId, clientSecret, requestTokenUrl, config.RedirectUrl, code); if (response.ErrorResponse != null) { return(MobileConnectStatus.Error(response.ErrorResponse.Error, response.ErrorResponse.ErrorDescription, null, response)); } if (!Validation.IsExpectedNonce(response.ResponseData.IdToken, expectedNonce)) { return(MobileConnectStatus.Error("invalid_nonce", "Nonce values do not match, this could suggest an attempted Replay Attack", null)); } } catch (MobileConnectInvalidArgumentException e) { return(MobileConnectStatus.Error("invalid_argument", string.Format("An argument was found to be invalid during the process. The argument was {0}.", e.Argument), e)); } catch (MobileConnectEndpointHttpException e) { return(MobileConnectStatus.Error("http_failure", "An HTTP failure occured while calling the operator token endpoint, the endpoint may be inaccessible", e)); } catch (Exception e) { return(MobileConnectStatus.Error("unknown_error", "A failure occured while requesting a token", e)); } return(MobileConnectStatus.Complete(response)); }
internal static async Task <MobileConnectStatus> RequestToken(IAuthenticationService authentication, IJWKeysetService jwks, DiscoveryResponse discoveryResponse, Uri redirectedUrl, string expectedState, string expectedNonce, MobileConnectConfig config, MobileConnectRequestOptions options) { RequestTokenResponse response; if (!IsUsableDiscoveryResponse(discoveryResponse)) { return(MobileConnectStatus.StartDiscovery()); } if (string.IsNullOrEmpty(expectedState)) { return(MobileConnectStatus.Error(ErrorCodes.InvalidArgument, "ExpectedState argument was not supplied, this is needed to prevent Cross-Site Request Forgery", null)); } if (string.IsNullOrEmpty(expectedNonce)) { return(MobileConnectStatus.Error(ErrorCodes.InvalidArgument, "expectedNonce argument was not supplied, this is needed to prevent Replay Attacks", null)); } var actualState = HttpUtils.ExtractQueryValue(redirectedUrl.Query, "state"); if (expectedState != actualState) { return(MobileConnectStatus.Error(ErrorCodes.InvalidState, "State values do not match, this could suggest an attempted Cross-Site Request Forgery", null)); } try { var code = HttpUtils.ExtractQueryValue(redirectedUrl.Query, "code"); var clientId = discoveryResponse.ResponseData.response.client_id ?? config.ClientId; var clientSecret = discoveryResponse.ResponseData.response.client_secret ?? config.ClientSecret; var requestTokenUrl = discoveryResponse.OperatorUrls.RequestTokenUrl; var issuer = discoveryResponse.ProviderMetadata.Issuer; var tokenTask = authentication.RequestTokenAsync(clientId, clientSecret, requestTokenUrl, config.RedirectUrl, code); var jwksTask = jwks.RetrieveJWKSAsync(discoveryResponse.OperatorUrls.JWKSUrl); // execute both tasks in parallel await Task.WhenAll(tokenTask, jwksTask).ConfigureAwait(false); response = tokenTask.Result; var maxSupportedVersion = discoveryResponse.ProviderMetadata?.MobileConnectVersionSupported == null ? "mc_v1.1" : discoveryResponse.ProviderMetadata.MobileConnectVersionSupported.MaxSupportedVersionString; return(HandleTokenResponse(authentication, response, clientId, issuer, expectedNonce, maxSupportedVersion, jwksTask.Result, options)); } catch (MobileConnectInvalidArgumentException e) { Log.Error(() => $"An invalid argument was passed to RequestToken arg={e.Argument}"); return(MobileConnectStatus.Error(ErrorCodes.InvalidArgument, string.Format("An argument was found to be invalid during the process. The argument was {0}.", e.Argument), e)); } catch (MobileConnectEndpointHttpException e) { Log.Error(() => $"A general http error occurred in RequestToken redirectedUrl={redirectedUrl} requestTokenUrl={discoveryResponse.OperatorUrls.RequestTokenUrl} jwksUrl={discoveryResponse.OperatorUrls.JWKSUrl}"); return(MobileConnectStatus.Error(ErrorCodes.HttpFailure, "An HTTP failure occured while calling the operator token endpoint, the endpoint may be inaccessible", e)); } catch (Exception e) { Log.Error(() => $"A general error occurred in RequestToken redirectedUrl={redirectedUrl} requestTokenUrl={discoveryResponse.OperatorUrls.RequestTokenUrl} jwksUrl={discoveryResponse.OperatorUrls.JWKSUrl}"); return(MobileConnectStatus.Error(ErrorCodes.Unknown, "A failure occured while requesting a token", e)); } }
internal static async Task <MobileConnectStatus> HandleUrlRedirect(IDiscovery discovery, IAuthentication authentication, Uri redirectedUrl, DiscoveryResponse discoveryResponse, string expectedState, string expectedNonce, MobileConnectConfig config) { if (HttpUtils.ExtractQueryValue(redirectedUrl.Query, "code") != null) { return(await RequestToken(authentication, discoveryResponse, redirectedUrl, expectedState, expectedNonce, config)); } else if (HttpUtils.ExtractQueryValue(redirectedUrl.Query, "mcc_mnc") != null) { return(await AttemptDiscoveryAfterOperatorSelection(discovery, redirectedUrl, config)); } string errorCode = HttpUtils.ExtractQueryValue(redirectedUrl.Query, "error") ?? "invalid_request"; string errorDesc = HttpUtils.ExtractQueryValue(redirectedUrl.Query, "error_description") ?? string.Format("Unable to parse next step using {0}", redirectedUrl.AbsoluteUri); return(MobileConnectStatus.Error(errorCode, errorDesc, null)); }
internal static async Task <MobileConnectStatus> RequestUserInfo(IIdentityService _identity, DiscoveryResponse discoveryResponse, string accessToken, MobileConnectConfig _config, MobileConnectRequestOptions options) { string userInfoUrl = discoveryResponse?.OperatorUrls?.UserInfoUrl; if (string.IsNullOrEmpty(userInfoUrl)) { Log.Error(() => $"UserInfo was not supported for issuer={discoveryResponse?.ProviderMetadata?.Issuer}"); return(MobileConnectStatus.Error(ErrorCodes.NotSupported, "UserInfo not supported with current operator", null)); } try { var response = await _identity.RequestUserInfo(userInfoUrl, accessToken); return(MobileConnectStatus.UserInfo(response)); } catch (MobileConnectInvalidArgumentException e) { Log.Error(() => $"An invalid argument was passed to RequestUserInfo arg={e.Argument}"); return(MobileConnectStatus.Error(ErrorCodes.InvalidArgument, string.Format("An argument was found to be invalid during the process. The argument was {0}.", e.Argument), e)); } catch (MobileConnectEndpointHttpException e) { Log.Error(() => $"A general http error occurred in RequestUserInfo userInfoUrl={userInfoUrl}"); return(MobileConnectStatus.Error(ErrorCodes.HttpFailure, "An HTTP failure occured while calling the operator token endpoint, the endpoint may be inaccessible", e)); } catch (Exception e) { Log.Error(() => $"A general error occurred in RequestUserInfo userInfoUrl={userInfoUrl}"); return(MobileConnectStatus.Error(ErrorCodes.Unknown, "A failure occured while requesting a token", e)); } }
internal static MobileConnectStatus StartAuthorization(IAuthentication authentication, DiscoveryResponse discoveryResponse, string encryptedMSISDN, string state, string nonce, MobileConnectConfig config, MobileConnectRequestOptions options) { StartAuthenticationResponse response; try { string clientId = discoveryResponse?.ResponseData?.response?.client_id ?? config.ClientId; string authorizationUrl = discoveryResponse?.OperatorUrls?.AuthorizationUrl; response = authentication.StartAuthentication(clientId, authorizationUrl, config.RedirectUrl, state, nonce, config.AuthorizationScope, config.AuthorizationMaxAge, config.AuthorizationAcrValues, encryptedMSISDN, options?.AuthenticationOptions); } catch (MobileConnectInvalidArgumentException e) { return(MobileConnectStatus.Error("invalid_argument", string.Format("An argument was found to be invalid during the process. The argument was {0}.", e.Argument), e)); } catch (Exception e) { return(MobileConnectStatus.Error("unknown_error", "An unknown error occured while generating an authorization url", e)); } return(MobileConnectStatus.Authorization(response.Url, state, nonce)); }
/// <summary> /// Initializes a new instance of the MobileConnectInterface class /// </summary> /// <param name="discovery">Instance of IDiscovery concrete implementation</param> /// <param name="authentication">Instance of IAuthentication concrete implementation</param> /// <param name="config">Configuration options</param> public MobileConnectInterface(IDiscovery discovery, IAuthentication authentication, MobileConnectConfig config) { this._discovery = discovery; this._authentication = authentication; this._config = config; }