From fa34ed249bbcaef3bf3d41b2617d62cb8ff793f8 Mon Sep 17 00:00:00 2001 From: Paul Schneider Date: Tue, 7 Jun 2016 14:32:43 +0200 Subject: [PATCH] integration https://github.com/XacronDevelopment/oauth-aspnet --- AuthorizationController.cs | 213 ----- .../ApiController/AccountController.cs | 0 .../{src => }/ApiController/GCMController.cs | 0 .../AuthenticationResponseChallenge.cs | 32 + .../AuthServer/AuthenticationResponseGrant.cs | 57 ++ .../AuthenticationTokenCreateContext.cs | 43 + .../AuthServer/AuthenticationTokenProvider.cs | 72 ++ .../AuthenticationTokenReceiveContext.cs | 43 + .../AuthServer/AuthorizeEndpointRequest.cs | 138 +++ .../AuthServer/BaseOAuthEndpointContext.cs | 40 + .../AuthServer/BaseValidatingClientContext.cs | 26 + .../Auth/AuthServer/BaseValidatingContext.cs | 113 +++ .../AuthServer/BaseValidatingTicketContext.cs | 54 ++ Yavsc/Auth/AuthServer/DefaultBehavior.cs | 40 + Yavsc/Auth/AuthServer/IApplicationStore.cs | 14 + .../IAuthenticationTokenProvider.cs | 14 + .../IOAuthAuthorizationServerProvider.cs | 172 ++++ .../OAuthAuthorizationServerHandler.cs | 816 ++++++++++++++++++ .../OAuthAuthorizationServerMiddleware.cs | 100 +++ .../OAuthAuthorizationServerOptions.cs | 136 +++ .../OAuthAuthorizationServerProvider.cs | 378 ++++++++ .../OAuthAuthorizeEndpointContext.cs | 34 + .../OAuthAuthorizeEndpointResponseContext.cs | 69 ++ Yavsc/Auth/AuthServer/OAuthConstants.cs | 70 ++ Yavsc/Auth/AuthServer/OAuthDefaults.cs | 15 + .../OAuthGrantAuthorizationCodeContext.cs | 21 + .../OAuthGrantClientCredentialsContext.cs | 36 + .../OAuthGrantCustomExtensionContext.cs | 42 + .../OAuthGrantRefreshTokenContext.cs | 30 + ...uthGrantResourceOwnerCredentialsContext.cs | 50 ++ Yavsc/Auth/AuthServer/OAuthMatchContext.cs | 74 ++ .../AuthServer/OAuthTokenEndpointContext.cs | 75 ++ .../OAuthTokenEndpointResponseContext.cs | 82 ++ .../OAuthValidateAuthorizeRequestContext.cs | 35 + ...AuthValidateClientAuthenticationContext.cs | 108 +++ .../OAuthValidateClientCredentialsContext.cs | 14 + .../OAuthValidateClientRedirectUriContext.cs | 74 ++ .../OAuthValidateTokenRequestContext.cs | 35 + Yavsc/Auth/AuthServer/TokenEndpointRequest.cs | 160 ++++ .../TokenEndpointRequestAuthorizationCode.cs | 23 + .../TokenEndpointRequestClientCredentials.cs | 18 + .../TokenEndpointRequestCustomExtension.cs | 17 + .../TokenEndpointRequestRefreshToken.cs | 21 + ...RequestResourceOwnerPasswordCredentials.cs | 26 + .../Tokens/TicketDataFormatTokenValidator.cs | 93 ++ Yavsc/{src => }/Auth/GoogleExtensions.cs | 0 Yavsc/{src => }/Auth/GoogleHandler.cs | 0 Yavsc/{src => }/Auth/GoogleHelper.cs | 0 Yavsc/{src => }/Auth/GoogleMiddleWare.cs | 0 .../Auth/GoogleOAuthCreatingTicket.cs | 0 Yavsc/{src => }/Auth/GoogleOptions.cs | 0 .../Auth/MonoDataProtectionProvider.cs | 0 Yavsc/{src => }/Auth/MonoDataProtector.cs | 0 .../Auth/MonoJwtSecurityTokenHandler.cs | 0 Yavsc/{src => }/Auth/RSAKeyUtils.cs | 0 .../Auth/RequiredScopesMiddleware.cs | 0 Yavsc/{src => }/Auth/TokenAuthOptions.cs | 0 Yavsc/{src => }/Auth/UserTokenProvider.cs | 0 Yavsc/{src => }/Auth/XmlEncryptor.cs | 0 .../Auth/Yavsc/YavscAuthenticationHandler.cs | 0 .../Yavsc/YavscAuthenticationMiddleware.cs | 0 .../YavscAuthenticationMiddlewareOptions.cs | 0 Yavsc/{src => }/Constants.cs | 6 + .../Controllers/AccountController.cs | 0 .../Controllers/ActivityController.cs | 0 .../Controllers/AdministrationController.cs | 0 .../Controllers/ApplicationController.cs | 1 + .../Controllers/BlogspotController.cs | 0 .../{src => }/Controllers/CircleController.cs | 0 .../Controllers/CommandController.cs | 0 .../Controllers/EstimateController.cs | 0 .../Controllers/FrontOfficeController.cs | 0 Yavsc/{src => }/Controllers/HomeController.cs | 0 .../{src => }/Controllers/ManageController.cs | 0 Yavsc/Controllers/OAuthController.cs | 158 ++++ .../{src => }/Controllers/TokenController.cs | 0 .../Controllers/UserFilesController.cs | 0 .../{src => }/Controllers/ValuesController.cs | 0 .../Extensions/AppBuilderExtensions.cs | 0 .../OAuthAuthorizationServerExtensions.cs | 61 ++ .../Extensions/SignalRBuilderExtension.cs | 0 .../{src => Filters}/LanguageActionFilter.cs | 0 Yavsc/{src => }/Formatters/PdfFormatter.cs | 0 Yavsc/{src => }/GoogleApis/CalendarApi.cs | 0 Yavsc/{src => }/GoogleApis/MapTracks.cs | 0 Yavsc/{src => }/GoogleApis/PeopleApi.cs | 0 Yavsc/{src => }/Helpers/AuthHelpers.cs | 0 Yavsc/{src => }/Helpers/CompanyInfoHelpers.cs | 0 Yavsc/{src => }/Helpers/EventHelpers.cs | 0 Yavsc/{src => }/Helpers/FileSystemHelpers.cs | 0 Yavsc/{src => }/Helpers/GoogleHelpers.cs | 0 Yavsc/{src => }/Helpers/ListItemHelpers.cs | 0 .../{src => }/Helpers/SimpleJsonPostMethod.cs | 0 Yavsc/{src => }/Helpers/TagHelpers.cs | 0 Yavsc/{src => }/Hubs/ChatHub.cs | 0 Yavsc/{src => }/Interfaces/IDataStore.cs | 0 Yavsc/{src => }/Interfaces/IIdentified.cs | 0 .../Interfaces/IPerformerSpecified.cs | 0 Yavsc/{src => }/Interfaces/IRating.cs | 0 Yavsc/{src => }/Interfaces/ITitle.cs | 0 Yavsc/{src => }/Model/Access/PerformerIM.cs | 0 Yavsc/{src => }/Model/Access/Publishing.cs | 0 Yavsc/{src => }/Model/Access/Rule.cs | 0 Yavsc/{src => }/Model/Access/RuleSet.cs | 0 Yavsc/{src => }/Model/Access/WhiteCard.cs | 0 Yavsc/{src => }/Model/ApplicationDbContext.cs | 8 +- Yavsc/{src => }/Model/Auth/Application.cs | 2 +- Yavsc/{src => }/Model/Auth/Scope.cs | 0 Yavsc/{src => }/Model/Auth/UserCredentials.cs | 0 Yavsc/{src => }/Model/Bank/AccountBalance.cs | 0 Yavsc/{src => }/Model/Bank/BalanceImpact.cs | 0 Yavsc/{src => }/Model/Billing/CommandLine.cs | 0 Yavsc/{src => }/Model/Billing/Commande.cs | 0 Yavsc/{src => }/Model/Billing/Estimate.cs | 0 .../Model/Billing/EstimateAgreement.cs | 0 .../Model/Billing/Service/ChatBilling.cs | 0 Yavsc/{src => }/Model/Billing/histoestim.cs | 0 Yavsc/{src => }/Model/Billing/satisfaction.cs | 0 Yavsc/{src => }/Model/Billing/writtings.cs | 0 Yavsc/{src => }/Model/Billing/wrtags.cs | 0 Yavsc/{src => }/Model/Blog/Blog.cs | 0 Yavsc/{src => }/Model/Blog/BlogAccess.cs | 0 .../Model/Blog/IBlogspotRepository.cs | 0 Yavsc/{src => }/Model/Blog/comment.cs | 0 Yavsc/{src => }/Model/Booking/BookQuery.cs | 0 .../Model/Calendar/ICalendarManager.cs | 0 .../{src => }/Model/Calendar/IFreeDateSet.cs | 0 Yavsc/{src => }/Model/Calendar/OpenDay.cs | 0 Yavsc/{src => }/Model/Calendar/Period.cs | 0 Yavsc/{src => }/Model/Calendar/Periodicity.cs | 0 .../Model/Calendar/PositionAndKeyphrase.cs | 0 .../{src => }/Model/Calendar/ProvidedEvent.cs | 0 Yavsc/{src => }/Model/Calendar/Schedule.cs | 0 Yavsc/{src => }/Model/Calendar/WeekDay.cs | 0 Yavsc/{src => }/Model/Edition/IDocument.cs | 0 Yavsc/{src => }/Model/Google/AuthToken.cs | 0 .../Google/Calendar/CalendarEventList.cs | 0 .../Model/Google/Calendar/CalendarList.cs | 0 .../Google/Calendar/CalendarListEntry.cs | 0 Yavsc/{src => }/Model/Google/GDate.cs | 0 .../Google/Messaging/GCMRegisterModel.cs | 0 .../Google/Messaging/MessageWithPayLoad.cs | 0 .../Messaging/MessageWithPayloadResponse.cs | 0 Yavsc/{src => }/Model/Google/People/People.cs | 0 Yavsc/{src => }/Model/Google/Resource.cs | 0 Yavsc/{src => }/Model/Google/Tracks/Entity.cs | 0 .../Model/Google/Tracks/EntityQuery.cs | 0 .../Model/Identity/ApplicationUser.cs | 0 .../Model/Identity/MobileAppDeclaration.cs | 0 .../{src => }/Model/Identity/OAuth2Tokens.cs | 0 .../{src => }/Model/Identity/passwrecovery.cs | 0 Yavsc/{src => }/Model/Market/BaseProduct.cs | 0 Yavsc/{src => }/Model/Market/Catalog.cs | 0 Yavsc/{src => }/Model/Market/Product.cs | 0 Yavsc/{src => }/Model/Market/Service.cs | 0 Yavsc/{src => }/Model/Messaging/BaseEvent.cs | 0 .../Model/Messaging/BookQueryEvent.cs | 0 .../{src => }/Model/Messaging/CircleEvent.cs | 0 .../{src => }/Model/Messaging/Notification.cs | 0 Yavsc/{src => }/Model/Messaging/YaEvent.cs | 0 Yavsc/{src => }/Model/Relationship/Circle.cs | 0 .../Model/Relationship/CircleMember.cs | 0 Yavsc/{src => }/Model/Relationship/Contact.cs | 0 .../{src => }/Model/Relationship/Location.cs | 0 Yavsc/{src => }/Model/Relationship/Tag.cs | 0 Yavsc/{src => }/Model/Relationship/Tagged.cs | 0 Yavsc/{src => }/Model/Workflow/Activity.cs | 0 .../{src => }/Model/Workflow/IRequisition.cs | 0 .../Model/Workflow/PerformerProfile.cs | 0 .../Model/Workflow/Process/Action.cs | 0 .../Model/Workflow/Process/Conjonction.cs | 0 .../Model/Workflow/Process/Disjonction.cs | 0 .../Model/Workflow/Process/InputValue.cs | 0 .../Workflow/Process/NamedRequisition.cs | 0 .../Model/Workflow/Process/Negation.cs | 0 .../{src => }/Model/Workflow/Process/Rule.cs | 0 Yavsc/{src => }/Model/Workflow/Projet.cs | 0 Yavsc/{src => }/Model/Workflow/Skill.cs | 0 Yavsc/{src => }/Model/Workflow/UserSkills.cs | 0 Yavsc/{src => }/Model/Workflow/hr.cs | 0 Yavsc/{src => }/Model/Workflow/taskdeps.cs | 0 Yavsc/{src => }/Model/Workflow/tasks.cs | 0 Yavsc/{src => }/Model/Workflow/wrfiles.cs | 0 .../Model/societe.com/CompanyInfo.cs | 0 Yavsc/{src => }/Services/IEmailSender.cs | 0 .../Services/IGoogleCloudMessageSender.cs | 0 Yavsc/{src => }/Services/ISmsSender.cs | 0 Yavsc/{src => }/Services/MessageServices.cs | 0 Yavsc/{src => }/Services/SIRENCheker.cs | 0 .../{src => }/Settings/CompanyInfoSettings.cs | 0 Yavsc/{src => }/Settings/EmailEntry.cs | 0 .../{src => }/Settings/GoogleAuthSettings.cs | 0 Yavsc/{src => }/Settings/OAuth2AppSettings.cs | 0 Yavsc/{src => }/Settings/PayPalSettings.cs | 0 Yavsc/{src => }/Settings/SiteSettings.cs | 0 Yavsc/{src => }/Settings/SmtpSettings.cs | 0 Yavsc/{src => }/Settings/ThirdPartyFiles.cs | 0 Yavsc/{src => }/Settings/TwilioSettings.cs | 0 Yavsc/Startup/Startup.OAuthHelpers.cs | 92 ++ Yavsc/{src => Startup}/Startup.cs | 168 ++-- .../Account/ChangePasswordBindingModel.cs | 0 .../ExternalLoginConfirmationViewModel.cs | 0 .../Account/ForgotPasswordViewModel.cs | 0 .../ViewModels/Account/LoginViewModel.cs | 0 .../ViewModels/Account/RegisterViewModel.cs | 0 .../Account/ResetPasswordViewModel.cs | 0 .../ViewModels/Account/SendCodeViewModel.cs | 0 .../ViewModels/Account/UnregisterViewModel.cs | 0 .../ViewModels/Account/VerifyCodeViewModel.cs | 0 .../ViewModels/Auth/AuthorisationHandlers.cs | 0 .../ViewModels/Auth/AuthorisationView.cs | 0 Yavsc/{src => }/ViewModels/Auth/ClaimTypes.cs | 0 .../Calendar/SetGoogleCalendarViewModel.cs | 0 .../Calendar/UpcomingEventsViewModel.cs | 0 .../Manage/AddPhoneNumberViewModel.cs | 0 .../Manage/ChangePasswordViewModel.cs | 0 .../Manage/ChangeUserNameViewModel.cs | 0 .../Manage/ConfigureTwoFactorViewModel.cs | 0 .../ViewModels/Manage/FactorViewModel.cs | 0 .../ViewModels/Manage/IndexViewModel.cs | 0 .../Manage/ManageLoginsViewModel.cs | 0 .../ViewModels/Manage/RemoveLoginViewModel.cs | 0 .../ViewModels/Manage/SetPasswordViewModel.cs | 0 .../Manage/VerifyPhoneNumberViewModel.cs | 0 .../ViewModels/UserFiles/BlogFilesPost.cs | 0 .../ViewModels/UserFiles/FileInfo.cs | 0 Yavsc/project.json | 54 +- Yavsc/project.json.new | 152 ---- Yavsc/project.lock.json | 394 +-------- Yavsc/src/Controllers/OAuthController.cs | 424 --------- Yavsc/src/Providers/OAuthProvider.cs | 150 ---- external/oauth-aspnet | 1 + global.json | 2 +- 233 files changed, 4000 insertions(+), 1396 deletions(-) delete mode 100644 AuthorizationController.cs rename Yavsc/{src => }/ApiController/AccountController.cs (100%) rename Yavsc/{src => }/ApiController/GCMController.cs (100%) create mode 100644 Yavsc/Auth/AuthServer/AuthenticationResponseChallenge.cs create mode 100644 Yavsc/Auth/AuthServer/AuthenticationResponseGrant.cs create mode 100644 Yavsc/Auth/AuthServer/AuthenticationTokenCreateContext.cs create mode 100644 Yavsc/Auth/AuthServer/AuthenticationTokenProvider.cs create mode 100644 Yavsc/Auth/AuthServer/AuthenticationTokenReceiveContext.cs create mode 100644 Yavsc/Auth/AuthServer/AuthorizeEndpointRequest.cs create mode 100644 Yavsc/Auth/AuthServer/BaseOAuthEndpointContext.cs create mode 100644 Yavsc/Auth/AuthServer/BaseValidatingClientContext.cs create mode 100644 Yavsc/Auth/AuthServer/BaseValidatingContext.cs create mode 100644 Yavsc/Auth/AuthServer/BaseValidatingTicketContext.cs create mode 100644 Yavsc/Auth/AuthServer/DefaultBehavior.cs create mode 100644 Yavsc/Auth/AuthServer/IApplicationStore.cs create mode 100644 Yavsc/Auth/AuthServer/IAuthenticationTokenProvider.cs create mode 100644 Yavsc/Auth/AuthServer/IOAuthAuthorizationServerProvider.cs create mode 100644 Yavsc/Auth/AuthServer/OAuthAuthorizationServerHandler.cs create mode 100644 Yavsc/Auth/AuthServer/OAuthAuthorizationServerMiddleware.cs create mode 100644 Yavsc/Auth/AuthServer/OAuthAuthorizationServerOptions.cs create mode 100644 Yavsc/Auth/AuthServer/OAuthAuthorizationServerProvider.cs create mode 100644 Yavsc/Auth/AuthServer/OAuthAuthorizeEndpointContext.cs create mode 100644 Yavsc/Auth/AuthServer/OAuthAuthorizeEndpointResponseContext.cs create mode 100644 Yavsc/Auth/AuthServer/OAuthConstants.cs create mode 100644 Yavsc/Auth/AuthServer/OAuthDefaults.cs create mode 100644 Yavsc/Auth/AuthServer/OAuthGrantAuthorizationCodeContext.cs create mode 100644 Yavsc/Auth/AuthServer/OAuthGrantClientCredentialsContext.cs create mode 100644 Yavsc/Auth/AuthServer/OAuthGrantCustomExtensionContext.cs create mode 100644 Yavsc/Auth/AuthServer/OAuthGrantRefreshTokenContext.cs create mode 100644 Yavsc/Auth/AuthServer/OAuthGrantResourceOwnerCredentialsContext.cs create mode 100644 Yavsc/Auth/AuthServer/OAuthMatchContext.cs create mode 100644 Yavsc/Auth/AuthServer/OAuthTokenEndpointContext.cs create mode 100644 Yavsc/Auth/AuthServer/OAuthTokenEndpointResponseContext.cs create mode 100644 Yavsc/Auth/AuthServer/OAuthValidateAuthorizeRequestContext.cs create mode 100644 Yavsc/Auth/AuthServer/OAuthValidateClientAuthenticationContext.cs create mode 100644 Yavsc/Auth/AuthServer/OAuthValidateClientCredentialsContext.cs create mode 100644 Yavsc/Auth/AuthServer/OAuthValidateClientRedirectUriContext.cs create mode 100644 Yavsc/Auth/AuthServer/OAuthValidateTokenRequestContext.cs create mode 100644 Yavsc/Auth/AuthServer/TokenEndpointRequest.cs create mode 100644 Yavsc/Auth/AuthServer/TokenEndpointRequestAuthorizationCode.cs create mode 100644 Yavsc/Auth/AuthServer/TokenEndpointRequestClientCredentials.cs create mode 100644 Yavsc/Auth/AuthServer/TokenEndpointRequestCustomExtension.cs create mode 100644 Yavsc/Auth/AuthServer/TokenEndpointRequestRefreshToken.cs create mode 100644 Yavsc/Auth/AuthServer/TokenEndpointRequestResourceOwnerPasswordCredentials.cs create mode 100644 Yavsc/Auth/AuthServer/Tokens/TicketDataFormatTokenValidator.cs rename Yavsc/{src => }/Auth/GoogleExtensions.cs (100%) rename Yavsc/{src => }/Auth/GoogleHandler.cs (100%) rename Yavsc/{src => }/Auth/GoogleHelper.cs (100%) rename Yavsc/{src => }/Auth/GoogleMiddleWare.cs (100%) rename Yavsc/{src => }/Auth/GoogleOAuthCreatingTicket.cs (100%) rename Yavsc/{src => }/Auth/GoogleOptions.cs (100%) rename Yavsc/{src => }/Auth/MonoDataProtectionProvider.cs (100%) rename Yavsc/{src => }/Auth/MonoDataProtector.cs (100%) rename Yavsc/{src => }/Auth/MonoJwtSecurityTokenHandler.cs (100%) rename Yavsc/{src => }/Auth/RSAKeyUtils.cs (100%) rename Yavsc/{src => }/Auth/RequiredScopesMiddleware.cs (100%) rename Yavsc/{src => }/Auth/TokenAuthOptions.cs (100%) rename Yavsc/{src => }/Auth/UserTokenProvider.cs (100%) rename Yavsc/{src => }/Auth/XmlEncryptor.cs (100%) rename Yavsc/{src => }/Auth/Yavsc/YavscAuthenticationHandler.cs (100%) rename Yavsc/{src => }/Auth/Yavsc/YavscAuthenticationMiddleware.cs (100%) rename Yavsc/{src => }/Auth/Yavsc/YavscAuthenticationMiddlewareOptions.cs (100%) rename Yavsc/{src => }/Constants.cs (91%) rename Yavsc/{src => }/Controllers/AccountController.cs (100%) rename Yavsc/{src => }/Controllers/ActivityController.cs (100%) rename Yavsc/{src => }/Controllers/AdministrationController.cs (100%) rename Yavsc/{src => }/Controllers/ApplicationController.cs (95%) rename Yavsc/{src => }/Controllers/BlogspotController.cs (100%) rename Yavsc/{src => }/Controllers/CircleController.cs (100%) rename Yavsc/{src => }/Controllers/CommandController.cs (100%) rename Yavsc/{src => }/Controllers/EstimateController.cs (100%) rename Yavsc/{src => }/Controllers/FrontOfficeController.cs (100%) rename Yavsc/{src => }/Controllers/HomeController.cs (100%) rename Yavsc/{src => }/Controllers/ManageController.cs (100%) create mode 100644 Yavsc/Controllers/OAuthController.cs rename Yavsc/{src => }/Controllers/TokenController.cs (100%) rename Yavsc/{src => }/Controllers/UserFilesController.cs (100%) rename Yavsc/{src => }/Controllers/ValuesController.cs (100%) rename Yavsc/{src => }/Extensions/AppBuilderExtensions.cs (100%) create mode 100644 Yavsc/Extensions/OAuthAuthorizationServerExtensions.cs rename Yavsc/{src => }/Extensions/SignalRBuilderExtension.cs (100%) rename Yavsc/{src => Filters}/LanguageActionFilter.cs (100%) rename Yavsc/{src => }/Formatters/PdfFormatter.cs (100%) rename Yavsc/{src => }/GoogleApis/CalendarApi.cs (100%) rename Yavsc/{src => }/GoogleApis/MapTracks.cs (100%) rename Yavsc/{src => }/GoogleApis/PeopleApi.cs (100%) rename Yavsc/{src => }/Helpers/AuthHelpers.cs (100%) rename Yavsc/{src => }/Helpers/CompanyInfoHelpers.cs (100%) rename Yavsc/{src => }/Helpers/EventHelpers.cs (100%) rename Yavsc/{src => }/Helpers/FileSystemHelpers.cs (100%) rename Yavsc/{src => }/Helpers/GoogleHelpers.cs (100%) rename Yavsc/{src => }/Helpers/ListItemHelpers.cs (100%) rename Yavsc/{src => }/Helpers/SimpleJsonPostMethod.cs (100%) rename Yavsc/{src => }/Helpers/TagHelpers.cs (100%) rename Yavsc/{src => }/Hubs/ChatHub.cs (100%) rename Yavsc/{src => }/Interfaces/IDataStore.cs (100%) rename Yavsc/{src => }/Interfaces/IIdentified.cs (100%) rename Yavsc/{src => }/Interfaces/IPerformerSpecified.cs (100%) rename Yavsc/{src => }/Interfaces/IRating.cs (100%) rename Yavsc/{src => }/Interfaces/ITitle.cs (100%) rename Yavsc/{src => }/Model/Access/PerformerIM.cs (100%) rename Yavsc/{src => }/Model/Access/Publishing.cs (100%) rename Yavsc/{src => }/Model/Access/Rule.cs (100%) rename Yavsc/{src => }/Model/Access/RuleSet.cs (100%) rename Yavsc/{src => }/Model/Access/WhiteCard.cs (100%) rename Yavsc/{src => }/Model/ApplicationDbContext.cs (93%) rename Yavsc/{src => }/Model/Auth/Application.cs (88%) rename Yavsc/{src => }/Model/Auth/Scope.cs (100%) rename Yavsc/{src => }/Model/Auth/UserCredentials.cs (100%) rename Yavsc/{src => }/Model/Bank/AccountBalance.cs (100%) rename Yavsc/{src => }/Model/Bank/BalanceImpact.cs (100%) rename Yavsc/{src => }/Model/Billing/CommandLine.cs (100%) rename Yavsc/{src => }/Model/Billing/Commande.cs (100%) rename Yavsc/{src => }/Model/Billing/Estimate.cs (100%) rename Yavsc/{src => }/Model/Billing/EstimateAgreement.cs (100%) rename Yavsc/{src => }/Model/Billing/Service/ChatBilling.cs (100%) rename Yavsc/{src => }/Model/Billing/histoestim.cs (100%) rename Yavsc/{src => }/Model/Billing/satisfaction.cs (100%) rename Yavsc/{src => }/Model/Billing/writtings.cs (100%) rename Yavsc/{src => }/Model/Billing/wrtags.cs (100%) rename Yavsc/{src => }/Model/Blog/Blog.cs (100%) rename Yavsc/{src => }/Model/Blog/BlogAccess.cs (100%) rename Yavsc/{src => }/Model/Blog/IBlogspotRepository.cs (100%) rename Yavsc/{src => }/Model/Blog/comment.cs (100%) rename Yavsc/{src => }/Model/Booking/BookQuery.cs (100%) rename Yavsc/{src => }/Model/Calendar/ICalendarManager.cs (100%) rename Yavsc/{src => }/Model/Calendar/IFreeDateSet.cs (100%) rename Yavsc/{src => }/Model/Calendar/OpenDay.cs (100%) rename Yavsc/{src => }/Model/Calendar/Period.cs (100%) rename Yavsc/{src => }/Model/Calendar/Periodicity.cs (100%) rename Yavsc/{src => }/Model/Calendar/PositionAndKeyphrase.cs (100%) rename Yavsc/{src => }/Model/Calendar/ProvidedEvent.cs (100%) rename Yavsc/{src => }/Model/Calendar/Schedule.cs (100%) rename Yavsc/{src => }/Model/Calendar/WeekDay.cs (100%) rename Yavsc/{src => }/Model/Edition/IDocument.cs (100%) rename Yavsc/{src => }/Model/Google/AuthToken.cs (100%) rename Yavsc/{src => }/Model/Google/Calendar/CalendarEventList.cs (100%) rename Yavsc/{src => }/Model/Google/Calendar/CalendarList.cs (100%) rename Yavsc/{src => }/Model/Google/Calendar/CalendarListEntry.cs (100%) rename Yavsc/{src => }/Model/Google/GDate.cs (100%) rename Yavsc/{src => }/Model/Google/Messaging/GCMRegisterModel.cs (100%) rename Yavsc/{src => }/Model/Google/Messaging/MessageWithPayLoad.cs (100%) rename Yavsc/{src => }/Model/Google/Messaging/MessageWithPayloadResponse.cs (100%) rename Yavsc/{src => }/Model/Google/People/People.cs (100%) rename Yavsc/{src => }/Model/Google/Resource.cs (100%) rename Yavsc/{src => }/Model/Google/Tracks/Entity.cs (100%) rename Yavsc/{src => }/Model/Google/Tracks/EntityQuery.cs (100%) rename Yavsc/{src => }/Model/Identity/ApplicationUser.cs (100%) rename Yavsc/{src => }/Model/Identity/MobileAppDeclaration.cs (100%) rename Yavsc/{src => }/Model/Identity/OAuth2Tokens.cs (100%) rename Yavsc/{src => }/Model/Identity/passwrecovery.cs (100%) rename Yavsc/{src => }/Model/Market/BaseProduct.cs (100%) rename Yavsc/{src => }/Model/Market/Catalog.cs (100%) rename Yavsc/{src => }/Model/Market/Product.cs (100%) rename Yavsc/{src => }/Model/Market/Service.cs (100%) rename Yavsc/{src => }/Model/Messaging/BaseEvent.cs (100%) rename Yavsc/{src => }/Model/Messaging/BookQueryEvent.cs (100%) rename Yavsc/{src => }/Model/Messaging/CircleEvent.cs (100%) rename Yavsc/{src => }/Model/Messaging/Notification.cs (100%) rename Yavsc/{src => }/Model/Messaging/YaEvent.cs (100%) rename Yavsc/{src => }/Model/Relationship/Circle.cs (100%) rename Yavsc/{src => }/Model/Relationship/CircleMember.cs (100%) rename Yavsc/{src => }/Model/Relationship/Contact.cs (100%) rename Yavsc/{src => }/Model/Relationship/Location.cs (100%) rename Yavsc/{src => }/Model/Relationship/Tag.cs (100%) rename Yavsc/{src => }/Model/Relationship/Tagged.cs (100%) rename Yavsc/{src => }/Model/Workflow/Activity.cs (100%) rename Yavsc/{src => }/Model/Workflow/IRequisition.cs (100%) rename Yavsc/{src => }/Model/Workflow/PerformerProfile.cs (100%) rename Yavsc/{src => }/Model/Workflow/Process/Action.cs (100%) rename Yavsc/{src => }/Model/Workflow/Process/Conjonction.cs (100%) rename Yavsc/{src => }/Model/Workflow/Process/Disjonction.cs (100%) rename Yavsc/{src => }/Model/Workflow/Process/InputValue.cs (100%) rename Yavsc/{src => }/Model/Workflow/Process/NamedRequisition.cs (100%) rename Yavsc/{src => }/Model/Workflow/Process/Negation.cs (100%) rename Yavsc/{src => }/Model/Workflow/Process/Rule.cs (100%) rename Yavsc/{src => }/Model/Workflow/Projet.cs (100%) rename Yavsc/{src => }/Model/Workflow/Skill.cs (100%) rename Yavsc/{src => }/Model/Workflow/UserSkills.cs (100%) rename Yavsc/{src => }/Model/Workflow/hr.cs (100%) rename Yavsc/{src => }/Model/Workflow/taskdeps.cs (100%) rename Yavsc/{src => }/Model/Workflow/tasks.cs (100%) rename Yavsc/{src => }/Model/Workflow/wrfiles.cs (100%) rename Yavsc/{src => }/Model/societe.com/CompanyInfo.cs (100%) rename Yavsc/{src => }/Services/IEmailSender.cs (100%) rename Yavsc/{src => }/Services/IGoogleCloudMessageSender.cs (100%) rename Yavsc/{src => }/Services/ISmsSender.cs (100%) rename Yavsc/{src => }/Services/MessageServices.cs (100%) rename Yavsc/{src => }/Services/SIRENCheker.cs (100%) rename Yavsc/{src => }/Settings/CompanyInfoSettings.cs (100%) rename Yavsc/{src => }/Settings/EmailEntry.cs (100%) rename Yavsc/{src => }/Settings/GoogleAuthSettings.cs (100%) rename Yavsc/{src => }/Settings/OAuth2AppSettings.cs (100%) rename Yavsc/{src => }/Settings/PayPalSettings.cs (100%) rename Yavsc/{src => }/Settings/SiteSettings.cs (100%) rename Yavsc/{src => }/Settings/SmtpSettings.cs (100%) rename Yavsc/{src => }/Settings/ThirdPartyFiles.cs (100%) rename Yavsc/{src => }/Settings/TwilioSettings.cs (100%) create mode 100644 Yavsc/Startup/Startup.OAuthHelpers.cs rename Yavsc/{src => Startup}/Startup.cs (83%) rename Yavsc/{src => }/ViewModels/Account/ChangePasswordBindingModel.cs (100%) rename Yavsc/{src => }/ViewModels/Account/ExternalLoginConfirmationViewModel.cs (100%) rename Yavsc/{src => }/ViewModels/Account/ForgotPasswordViewModel.cs (100%) rename Yavsc/{src => }/ViewModels/Account/LoginViewModel.cs (100%) rename Yavsc/{src => }/ViewModels/Account/RegisterViewModel.cs (100%) rename Yavsc/{src => }/ViewModels/Account/ResetPasswordViewModel.cs (100%) rename Yavsc/{src => }/ViewModels/Account/SendCodeViewModel.cs (100%) rename Yavsc/{src => }/ViewModels/Account/UnregisterViewModel.cs (100%) rename Yavsc/{src => }/ViewModels/Account/VerifyCodeViewModel.cs (100%) rename Yavsc/{src => }/ViewModels/Auth/AuthorisationHandlers.cs (100%) rename Yavsc/{src => }/ViewModels/Auth/AuthorisationView.cs (100%) rename Yavsc/{src => }/ViewModels/Auth/ClaimTypes.cs (100%) rename Yavsc/{src => }/ViewModels/Calendar/SetGoogleCalendarViewModel.cs (100%) rename Yavsc/{src => }/ViewModels/Calendar/UpcomingEventsViewModel.cs (100%) rename Yavsc/{src => }/ViewModels/Manage/AddPhoneNumberViewModel.cs (100%) rename Yavsc/{src => }/ViewModels/Manage/ChangePasswordViewModel.cs (100%) rename Yavsc/{src => }/ViewModels/Manage/ChangeUserNameViewModel.cs (100%) rename Yavsc/{src => }/ViewModels/Manage/ConfigureTwoFactorViewModel.cs (100%) rename Yavsc/{src => }/ViewModels/Manage/FactorViewModel.cs (100%) rename Yavsc/{src => }/ViewModels/Manage/IndexViewModel.cs (100%) rename Yavsc/{src => }/ViewModels/Manage/ManageLoginsViewModel.cs (100%) rename Yavsc/{src => }/ViewModels/Manage/RemoveLoginViewModel.cs (100%) rename Yavsc/{src => }/ViewModels/Manage/SetPasswordViewModel.cs (100%) rename Yavsc/{src => }/ViewModels/Manage/VerifyPhoneNumberViewModel.cs (100%) rename Yavsc/{src => }/ViewModels/UserFiles/BlogFilesPost.cs (100%) rename Yavsc/{src => }/ViewModels/UserFiles/FileInfo.cs (100%) delete mode 100755 Yavsc/project.json.new delete mode 100644 Yavsc/src/Controllers/OAuthController.cs delete mode 100644 Yavsc/src/Providers/OAuthProvider.cs create mode 160000 external/oauth-aspnet diff --git a/AuthorizationController.cs b/AuthorizationController.cs deleted file mode 100644 index d639653e..00000000 --- a/AuthorizationController.cs +++ /dev/null @@ -1,213 +0,0 @@ -using System; -using System.Linq; -using System.Security.Claims; -using System.Threading; -using System.Threading.Tasks; -using AspNet.Security.OpenIdConnect.Extensions; -using AspNet.Security.OpenIdConnect.Server; -using Microsoft.AspNetCore.Authentication; -using Microsoft.AspNetCore.Authentication.Cookies; -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Http.Authentication; -using Microsoft.AspNetCore.Mvc; -using Microsoft.EntityFrameworkCore; -using Microsoft.IdentityModel.Protocols.OpenIdConnect; -using Mvc.Server.Models; - -namespace Mvc.Server.Controllers { - public class AuthorizationController : Controller { - private readonly ApplicationContext database; - - public AuthorizationController(ApplicationContext database) { - this.database = database; - } - - [HttpGet("~/connect/authorize"), HttpPost("~/connect/authorize")] - public async Task Authorize(CancellationToken cancellationToken) { - // Note: when a fatal error occurs during the request processing, an OpenID Connect response - // is prematurely forged and added to the ASP.NET context by OpenIdConnectServerHandler. - // You can safely remove this part and let ASOS automatically handle the unrecoverable errors - // by switching ApplicationCanDisplayErrors to false in Startup.cs. - var response = HttpContext.GetOpenIdConnectResponse(); - if (response != null) { - return View("Error", response); - } - - // Extract the authorization request from the ASP.NET environment. - var request = HttpContext.GetOpenIdConnectRequest(); - if (request == null) { - return View("Error", new OpenIdConnectMessage { - Error = OpenIdConnectConstants.Errors.ServerError, - ErrorDescription = "An internal error has occurred" - }); - } - - // Note: authentication could be theorically enforced at the filter level via AuthorizeAttribute - // but this authorization endpoint accepts both GET and POST requests while the cookie middleware - // only uses 302 responses to redirect the user agent to the login page, making it incompatible with POST. - // To work around this limitation, the OpenID Connect request is automatically saved in the cache and will be - // restored by the OpenID Connect server middleware after the external authentication process has been completed. - if (!User.Identities.Any(identity => identity.IsAuthenticated)) { - return Challenge(new AuthenticationProperties { - RedirectUri = Url.Action(nameof(Authorize), new { - request_id = request.GetRequestId() - }) - }); - } - - // Note: ASOS automatically ensures that an application corresponds to the client_id specified - // in the authorization request by calling IOpenIdConnectServerProvider.ValidateAuthorizationRequest. - // In theory, this null check shouldn't be needed, but a race condition could occur if you - // manually removed the application details from the database after the initial check made by ASOS. - var application = await GetApplicationAsync(request.ClientId, cancellationToken); - if (application == null) { - return View("Error", new OpenIdConnectMessage { - Error = OpenIdConnectConstants.Errors.InvalidClient, - ErrorDescription = "Details concerning the calling client application cannot be found in the database" - }); - } - - // Note: in a real world application, you'd probably prefer creating a specific view model. - return View("Authorize", Tuple.Create(request, application)); - } - - [Authorize, HttpPost("~/connect/authorize/accept"), ValidateAntiForgeryToken] - public async Task Accept(CancellationToken cancellationToken) { - var response = HttpContext.GetOpenIdConnectResponse(); - if (response != null) { - return View("Error", response); - } - - var request = HttpContext.GetOpenIdConnectRequest(); - if (request == null) { - return View("Error", new OpenIdConnectMessage { - Error = OpenIdConnectConstants.Errors.ServerError, - ErrorDescription = "An internal error has occurred" - }); - } - - // Create a new ClaimsIdentity containing the claims that - // will be used to create an id_token, a token or a code. - var identity = new ClaimsIdentity(OpenIdConnectServerDefaults.AuthenticationScheme); - - // Copy the claims retrieved from the external identity provider - // (e.g Google, Facebook, a WS-Fed provider or another OIDC server). - foreach (var claim in HttpContext.User.Claims) { - // Allow ClaimTypes.Name to be added in the id_token. - // ClaimTypes.NameIdentifier is automatically added, even if its - // destination is not defined or doesn't include "id_token". - // The other claims won't be visible for the client application. - if (claim.Type == ClaimTypes.Name) { - claim.SetDestinations(OpenIdConnectConstants.Destinations.AccessToken, - OpenIdConnectConstants.Destinations.IdentityToken); - } - - identity.AddClaim(claim); - } - - var application = await GetApplicationAsync(request.ClientId, cancellationToken); - if (application == null) { - return View("Error", new OpenIdConnectMessage { - Error = OpenIdConnectConstants.Errors.InvalidClient, - ErrorDescription = "Details concerning the calling client application cannot be found in the database" - }); - } - - // Create a new ClaimsIdentity containing the claims associated with the application. - // Note: setting identity.Actor is not mandatory but can be useful to access - // the whole delegation chain from the resource server (see ResourceController.cs). - identity.Actor = new ClaimsIdentity(OpenIdConnectServerDefaults.AuthenticationScheme); - identity.Actor.AddClaim(ClaimTypes.NameIdentifier, application.ApplicationID); - - identity.Actor.AddClaim(ClaimTypes.Name, application.DisplayName, - OpenIdConnectConstants.Destinations.AccessToken, - OpenIdConnectConstants.Destinations.IdentityToken); - - // Create a new authentication ticket holding the user identity. - var ticket = new AuthenticationTicket( - new ClaimsPrincipal(identity), - new AuthenticationProperties(), - OpenIdConnectServerDefaults.AuthenticationScheme); - - // Set the list of scopes granted to the client application. - // Note: this sample always grants the "openid", "email" and "profile" scopes - // when they are requested by the client application: a real world application - // would probably display a form allowing to select the scopes to grant. - ticket.SetScopes(new[] { - /* openid: */ OpenIdConnectConstants.Scopes.OpenId, - /* email: */ OpenIdConnectConstants.Scopes.Email, - /* profile: */ OpenIdConnectConstants.Scopes.Profile, - /* offline_access: */ OpenIdConnectConstants.Scopes.OfflineAccess - }.Intersect(request.GetScopes())); - - // Set the resources servers the access token should be issued for. - ticket.SetResources("resource_server"); - - // Returning a SignInResult will ask ASOS to serialize the specified identity to build appropriate tokens. - // Note: you should always make sure the identities you return contain ClaimTypes.NameIdentifier claim. - // In this sample, the identity always contains the name identifier returned by the external provider. - return SignIn(ticket.Principal, ticket.Properties, ticket.AuthenticationScheme); - } - - [Authorize, HttpPost("~/connect/authorize/deny"), ValidateAntiForgeryToken] - public IActionResult Deny(CancellationToken cancellationToken) { - var response = HttpContext.GetOpenIdConnectResponse(); - if (response != null) { - return View("Error", response); - } - - var request = HttpContext.GetOpenIdConnectRequest(); - if (request == null) { - return View("Error", new OpenIdConnectMessage { - Error = OpenIdConnectConstants.Errors.ServerError, - ErrorDescription = "An internal error has occurred" - }); - } - - // Notify ASOS that the authorization grant has been denied by the resource owner. - // Note: OpenIdConnectServerHandler will automatically take care of redirecting - // the user agent to the client application using the appropriate response_mode. - return Forbid(OpenIdConnectServerDefaults.AuthenticationScheme); - } - - [HttpGet("~/connect/logout")] - public async Task Logout(CancellationToken cancellationToken) { - var response = HttpContext.GetOpenIdConnectResponse(); - if (response != null) { - return View("Error", response); - } - - // When invoked, the logout endpoint might receive an unauthenticated request if the server cookie has expired. - // When the client application sends an id_token_hint parameter, the corresponding identity can be retrieved - // using AuthenticateAsync or using User when the authorization server is declared as AuthenticationMode.Active. - var identity = await HttpContext.Authentication.AuthenticateAsync(OpenIdConnectServerDefaults.AuthenticationScheme); - - var request = HttpContext.GetOpenIdConnectRequest(); - if (request == null) { - return View("Error", new OpenIdConnectMessage { - Error = OpenIdConnectConstants.Errors.ServerError, - ErrorDescription = "An internal error has occurred" - }); - } - - return View("Logout", Tuple.Create(request, identity)); - } - - [HttpPost("~/connect/logout")] - [ValidateAntiForgeryToken] - public ActionResult Logout() { - // Returning a SignOutResult will ask the cookies middleware to delete the local cookie created when - // the user agent is redirected from the external identity provider after a successful authentication flow - // and will redirect the user agent to the post_logout_redirect_uri specified by the client application. - return SignOut("ServerCookie", OpenIdConnectServerDefaults.AuthenticationScheme); - } - - protected virtual Task GetApplicationAsync(string identifier, CancellationToken cancellationToken) { - // Retrieve the application details corresponding to the requested client_id. - return (from application in database.Applications - where application.ApplicationID == identifier - select application).SingleOrDefaultAsync(cancellationToken); - } - } -} \ No newline at end of file diff --git a/Yavsc/src/ApiController/AccountController.cs b/Yavsc/ApiController/AccountController.cs similarity index 100% rename from Yavsc/src/ApiController/AccountController.cs rename to Yavsc/ApiController/AccountController.cs diff --git a/Yavsc/src/ApiController/GCMController.cs b/Yavsc/ApiController/GCMController.cs similarity index 100% rename from Yavsc/src/ApiController/GCMController.cs rename to Yavsc/ApiController/GCMController.cs diff --git a/Yavsc/Auth/AuthServer/AuthenticationResponseChallenge.cs b/Yavsc/Auth/AuthServer/AuthenticationResponseChallenge.cs new file mode 100644 index 00000000..4cd7143d --- /dev/null +++ b/Yavsc/Auth/AuthServer/AuthenticationResponseChallenge.cs @@ -0,0 +1,32 @@ +using Microsoft.AspNet.Http.Authentication; + +namespace OAuth.AspNet.AuthServer +{ + /// + /// Exposes the security.Challenge environment value as a strong type. + /// + public class AuthenticationResponseChallenge + { + /// + /// Initializes a new instance of the class + /// + /// + /// + public AuthenticationResponseChallenge(string[] authenticationTypes, AuthenticationProperties properties) + { + AuthenticationTypes = authenticationTypes; + Properties = properties ?? new AuthenticationProperties(); + } + + /// + /// List of the authentication types that should send a challenge in the response. + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays", Justification = "By design")] + public string[] AuthenticationTypes { get; private set; } + + /// + /// Dictionary used to store state values about the authentication session. + /// + public AuthenticationProperties Properties { get; private set; } + } +} diff --git a/Yavsc/Auth/AuthServer/AuthenticationResponseGrant.cs b/Yavsc/Auth/AuthServer/AuthenticationResponseGrant.cs new file mode 100644 index 00000000..28900a4e --- /dev/null +++ b/Yavsc/Auth/AuthServer/AuthenticationResponseGrant.cs @@ -0,0 +1,57 @@ +using Microsoft.AspNet.Http.Authentication; +using System; +using System.Linq; +using System.Security.Claims; + +namespace OAuth.AspNet.AuthServer +{ + /// + /// Exposes the security.SignIn environment value as a strong type. + /// + public class AuthenticationResponseGrant + { + /// + /// Initializes a new instance of the class. + /// + /// + /// + public AuthenticationResponseGrant(ClaimsIdentity identity, AuthenticationProperties properties) + { + Principal = new ClaimsPrincipal(identity); + Identity = identity; + Properties = properties; + } + + /// + /// Initializes a new instance of the class. + /// + /// + /// + public AuthenticationResponseGrant(ClaimsPrincipal principal, AuthenticationProperties properties) + { + if (principal == null) + { + throw new ArgumentNullException("principal"); + } + + Principal = principal; + Identity = principal.Identities.FirstOrDefault(); + Properties = properties; + } + + /// + /// The identity associated with the user sign in. + /// + public ClaimsIdentity Identity { get; private set; } + + /// + /// The security principal associated with the user sign in. + /// + public ClaimsPrincipal Principal { get; private set; } + + /// + /// Dictionary used to store state values about the authentication session. + /// + public AuthenticationProperties Properties { get; private set; } + } +} diff --git a/Yavsc/Auth/AuthServer/AuthenticationTokenCreateContext.cs b/Yavsc/Auth/AuthServer/AuthenticationTokenCreateContext.cs new file mode 100644 index 00000000..4dda1538 --- /dev/null +++ b/Yavsc/Auth/AuthServer/AuthenticationTokenCreateContext.cs @@ -0,0 +1,43 @@ +using Microsoft.AspNet.Http; +using Microsoft.AspNet.Authentication; +using System; + +namespace OAuth.AspNet.AuthServer +{ + + public class AuthenticationTokenCreateContext : BaseContext + { + private readonly ISecureDataFormat _secureDataFormat; + + public AuthenticationTokenCreateContext(HttpContext context, ISecureDataFormat secureDataFormat, AuthenticationTicket ticket) : base(context) + { + if (secureDataFormat == null) + throw new ArgumentNullException(nameof(secureDataFormat)); + + if (ticket == null) + throw new ArgumentNullException(nameof(ticket)); + + _secureDataFormat = secureDataFormat; + + Ticket = ticket; + } + + public string Token { get; protected set; } + + public AuthenticationTicket Ticket { get; protected set; } + + public string SerializeTicket() + { + return _secureDataFormat.Protect(Ticket); + } + + public void SetToken(string tokenValue) + { + if (tokenValue == null) + throw new ArgumentNullException(nameof(tokenValue)); + + Token = tokenValue; + } + } + +} diff --git a/Yavsc/Auth/AuthServer/AuthenticationTokenProvider.cs b/Yavsc/Auth/AuthServer/AuthenticationTokenProvider.cs new file mode 100644 index 00000000..aac9bcb7 --- /dev/null +++ b/Yavsc/Auth/AuthServer/AuthenticationTokenProvider.cs @@ -0,0 +1,72 @@ +using System; +using System.Threading.Tasks; + +namespace OAuth.AspNet.AuthServer +{ + + public class AuthenticationTokenProvider : IAuthenticationTokenProvider + { + public Action OnCreate { get; set; } + public Func OnCreateAsync { get; set; } + public Action OnReceive { get; set; } + public Func OnReceiveAsync { get; set; } + + public virtual void Create(AuthenticationTokenCreateContext context) + { + if (OnCreateAsync != null && OnCreate == null) + { + throw new InvalidOperationException("Authentication token did not provide an OnCreate method."); + } + if (OnCreate != null) + { + OnCreate.Invoke(context); + } + } + + public virtual async Task CreateAsync(AuthenticationTokenCreateContext context) + { + if (OnCreateAsync != null && OnCreate == null) + { + throw new InvalidOperationException("Authentication token did not provide an OnCreate method."); + } + if (OnCreateAsync != null) + { + await OnCreateAsync.Invoke(context); + } + else + { + Create(context); + } + } + + public virtual void Receive(AuthenticationTokenReceiveContext context) + { + if (OnReceiveAsync != null && OnReceive == null) + { + throw new InvalidOperationException("Authentication token did not provide an OnReceive method."); + } + + if (OnReceive != null) + { + OnReceive.Invoke(context); + } + } + + public virtual async Task ReceiveAsync(AuthenticationTokenReceiveContext context) + { + if (OnReceiveAsync != null && OnReceive == null) + { + throw new InvalidOperationException("Authentication token did not provide an OnReceive method."); + } + if (OnReceiveAsync != null) + { + await OnReceiveAsync.Invoke(context); + } + else + { + Receive(context); + } + } + } + +} diff --git a/Yavsc/Auth/AuthServer/AuthenticationTokenReceiveContext.cs b/Yavsc/Auth/AuthServer/AuthenticationTokenReceiveContext.cs new file mode 100644 index 00000000..96b3cc0b --- /dev/null +++ b/Yavsc/Auth/AuthServer/AuthenticationTokenReceiveContext.cs @@ -0,0 +1,43 @@ +using Microsoft.AspNet.Http; +using Microsoft.AspNet.Authentication; +using System; + +namespace OAuth.AspNet.AuthServer +{ + + public class AuthenticationTokenReceiveContext : BaseContext + { + private readonly ISecureDataFormat _secureDataFormat; + + public AuthenticationTokenReceiveContext(HttpContext context, ISecureDataFormat secureDataFormat, string token) : base(context) + { + if (secureDataFormat == null) + throw new ArgumentNullException(nameof(secureDataFormat)); + + if (token == null) + throw new ArgumentNullException(nameof(token)); + + _secureDataFormat = secureDataFormat; + + Token = token; + } + + public string Token { get; protected set; } + + public AuthenticationTicket Ticket { get; protected set; } + + public void DeserializeTicket(string protectedData) + { + Ticket = _secureDataFormat.Unprotect(protectedData); + } + + public void SetTicket(AuthenticationTicket ticket) + { + if (ticket == null) + throw new ArgumentNullException(nameof(ticket)); + + Ticket = ticket; + } + } + +} diff --git a/Yavsc/Auth/AuthServer/AuthorizeEndpointRequest.cs b/Yavsc/Auth/AuthServer/AuthorizeEndpointRequest.cs new file mode 100644 index 00000000..ee604b40 --- /dev/null +++ b/Yavsc/Auth/AuthServer/AuthorizeEndpointRequest.cs @@ -0,0 +1,138 @@ +using Microsoft.AspNet.Http; +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; + +namespace OAuth.AspNet.AuthServer +{ + + /// + /// Data object representing the information contained in the query string of an Authorize endpoint request. + /// + public class AuthorizeEndpointRequest + { + /// + /// Creates a new instance populated with values from the query string parameters. + /// + /// Query string parameters from a request. + public AuthorizeEndpointRequest(IReadableStringCollection parameters) + { + if (parameters == null) + { + throw new ArgumentNullException("parameters"); + } + + Scope = new List(); + + foreach (var parameter in parameters) + { + AddParameter(parameter.Key, parameters[parameter.Key]); + } + } + + /// + /// The "response_type" query string parameter of the Authorize request. Known values are "code" and "token". + /// + public string ResponseType { get; set; } + + /// + /// The "response_mode" query string parameter of the Authorize request. Known values are "query", "fragment" and "form_post" + /// See also, http://openid.net/specs/oauth-v2-form-post-response-mode-1_0.html + /// + public string ResponseMode { get; set; } + + /// + /// The "client_id" query string parameter of the Authorize request. + /// + public string ClientId { get; set; } + + /// + /// The "redirect_uri" query string parameter of the Authorize request. May be absent if the server should use the + /// redirect uri known to be registered to the client id. + /// + [SuppressMessage("Microsoft.Design", "CA1056:UriPropertiesShouldNotBeStrings", Justification = "By design")] + public string RedirectUri { get; set; } + + /// + /// The "scope" query string parameter of the Authorize request. May be absent if the server should use default scopes. + /// + public IList Scope { get; private set; } + + /// + /// The "scope" query string parameter of the Authorize request. May be absent if the client does not require state to be + /// included when returning to the RedirectUri. + /// + public string State { get; set; } + + /// + /// True if the "response_type" query string parameter is "code". + /// See also, http://tools.ietf.org/html/rfc6749#section-4.1.1 + /// + public bool IsAuthorizationCodeGrantType + { + get { return ContainsGrantType(Constants.ResponseTypes.Code); } + } + + /// + /// True if the "response_type" query string parameter is "token". + /// See also, http://tools.ietf.org/html/rfc6749#section-4.2.1 + /// + public bool IsImplicitGrantType + { + get { return ContainsGrantType(Constants.ResponseTypes.Token); } + } + + public bool IsFormPostResponseMode + { + get { return string.Equals(ResponseMode, Constants.ResponseModes.FormPost, StringComparison.Ordinal); } + } + + /// + /// True if the "response_type" query string contains the passed responseType. + /// See also, http://openid.net/specs/oauth-v2-multiple-response-types-1_0.html + /// + /// The responseType that is expected within the "response_type" query string + /// True if the "response_type" query string contains the passed responseType. + public bool ContainsGrantType(string responseType) + { + var parts = ResponseType.Split(' '); + foreach (var part in parts) + { + if (string.Equals(part, responseType, StringComparison.Ordinal)) + { + return true; + } + } + return false; + } + + private void AddParameter(string name, string value) + { + if (string.Equals(name, Constants.Parameters.ResponseType, StringComparison.Ordinal)) + { + ResponseType = value; + } + else if (string.Equals(name, Constants.Parameters.ClientId, StringComparison.Ordinal)) + { + ClientId = value; + } + else if (string.Equals(name, Constants.Parameters.RedirectUri, StringComparison.Ordinal)) + { + RedirectUri = value; + } + else if (string.Equals(name, Constants.Parameters.Scope, StringComparison.Ordinal)) + { + Scope = value.Split(' '); + } + else if (string.Equals(name, Constants.Parameters.State, StringComparison.Ordinal)) + { + State = value; + } + else if (string.Equals(name, Constants.Parameters.ResponseMode, StringComparison.Ordinal)) + { + ResponseMode = value; + } + } + } + +} diff --git a/Yavsc/Auth/AuthServer/BaseOAuthEndpointContext.cs b/Yavsc/Auth/AuthServer/BaseOAuthEndpointContext.cs new file mode 100644 index 00000000..17099070 --- /dev/null +++ b/Yavsc/Auth/AuthServer/BaseOAuthEndpointContext.cs @@ -0,0 +1,40 @@ +using Microsoft.AspNet.Authentication; +using Microsoft.AspNet.Http; +using System; + +namespace OAuth.AspNet.AuthServer +{ + + /// + /// Base class for OAuth server endpoint contexts + /// + public class BaseOAuthEndpointContext : BaseContext + { + #region Constructors + + /// + /// Creates a new instance of . + /// + /// The to use for this endpoint context. + /// The to use for this endpoint context. + public BaseOAuthEndpointContext(HttpContext context, OAuthAuthorizationServerOptions options) : base(context) + { + if (options == null) + throw new ArgumentNullException(nameof(options)); + + Options = options; + } + + #endregion + + #region Public Members + + /// + /// Gets the OAuth server options. + /// + public OAuthAuthorizationServerOptions Options { get; } + + #endregion + } + +} diff --git a/Yavsc/Auth/AuthServer/BaseValidatingClientContext.cs b/Yavsc/Auth/AuthServer/BaseValidatingClientContext.cs new file mode 100644 index 00000000..d2df770b --- /dev/null +++ b/Yavsc/Auth/AuthServer/BaseValidatingClientContext.cs @@ -0,0 +1,26 @@ +using Microsoft.AspNet.Http; + +namespace OAuth.AspNet.AuthServer +{ + + /// + /// Base class used for certain event contexts + /// + public abstract class BaseValidatingClientContext : BaseValidatingContext + { + /// + /// Initializes base class used for certain event contexts + /// + protected BaseValidatingClientContext(HttpContext context, OAuthAuthorizationServerOptions options, string clientId) : base(context, options) + { + ClientId = clientId; + } + + /// + /// The "client_id" parameter for the current request. The Authorization Server application is responsible for + /// validating this value identifies a registered client. + /// + public string ClientId { get; protected set; } + } + +} diff --git a/Yavsc/Auth/AuthServer/BaseValidatingContext.cs b/Yavsc/Auth/AuthServer/BaseValidatingContext.cs new file mode 100644 index 00000000..6252bc17 --- /dev/null +++ b/Yavsc/Auth/AuthServer/BaseValidatingContext.cs @@ -0,0 +1,113 @@ +using Microsoft.AspNet.Authentication; +using Microsoft.AspNet.Http; + +namespace OAuth.AspNet.AuthServer +{ + + /// + /// Base class used for certain event contexts + /// + public abstract class BaseValidatingContext : BaseContext + { + /// + /// Initializes base class used for certain event contexts + /// + protected BaseValidatingContext(HttpContext context, TOptions options) : base(context) + { + Options = options; + } + + /// + /// The context options. + /// + public TOptions Options { get; private set; } + + /// + /// True if application code has called any of the Validate methods on this context. + /// + public bool IsValidated { get; private set; } + + /// + /// True if application code has called any of the SetError methods on this context. + /// + public bool HasError { get; private set; } + + /// + /// The error argument provided when SetError was called on this context. This is eventually + /// returned to the client app as the OAuth "error" parameter. + /// + public string Error { get; private set; } + + /// + /// The optional errorDescription argument provided when SetError was called on this context. This is eventually + /// returned to the client app as the OAuth "error_description" parameter. + /// + public string ErrorDescription { get; private set; } + + /// + /// The optional errorUri argument provided when SetError was called on this context. This is eventually + /// returned to the client app as the OAuth "error_uri" parameter. + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1056:UriPropertiesShouldNotBeStrings", Justification = "error_uri is a string value in the protocol")] + public string ErrorUri { get; private set; } + + /// + /// Marks this context as validated by the application. IsValidated becomes true and HasError becomes false as a result of calling. + /// + /// True if the validation has taken effect. + public virtual bool Validated() + { + IsValidated = true; + HasError = false; + return true; + } + + /// + /// Marks this context as not validated by the application. IsValidated and HasError become false as a result of calling. + /// + public virtual void Rejected() + { + IsValidated = false; + HasError = false; + } + + /// + /// Marks this context as not validated by the application and assigns various error information properties. + /// HasError becomes true and IsValidated becomes false as a result of calling. + /// + /// Assigned to the Error property + public void SetError(string error) + { + SetError(error, null); + } + + /// + /// Marks this context as not validated by the application and assigns various error information properties. + /// HasError becomes true and IsValidated becomes false as a result of calling. + /// + /// Assigned to the Error property + /// Assigned to the ErrorDescription property + public void SetError(string error, string errorDescription) + { + SetError(error, errorDescription, null); + } + + /// + /// Marks this context as not validated by the application and assigns various error information properties. + /// HasError becomes true and IsValidated becomes false as a result of calling. + /// + /// Assigned to the Error property + /// Assigned to the ErrorDescription property + /// Assigned to the ErrorUri property + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "2#", Justification = "error_uri is a string value in the protocol")] + public void SetError(string error, string errorDescription, string errorUri) + { + Error = error; + ErrorDescription = errorDescription; + ErrorUri = errorUri; + Rejected(); + HasError = true; + } + } + +} diff --git a/Yavsc/Auth/AuthServer/BaseValidatingTicketContext.cs b/Yavsc/Auth/AuthServer/BaseValidatingTicketContext.cs new file mode 100644 index 00000000..c0697112 --- /dev/null +++ b/Yavsc/Auth/AuthServer/BaseValidatingTicketContext.cs @@ -0,0 +1,54 @@ +using Microsoft.AspNet.Authentication; +using Microsoft.AspNet.Http; +using Microsoft.AspNet.Http.Authentication; +using System.Security.Claims; + +namespace OAuth.AspNet.AuthServer +{ + + /// + /// Base class used for certain event contexts + /// + public abstract class BaseValidatingTicketContext : BaseValidatingContext where TOptions : AuthenticationOptions + { + /// + /// Initializes base class used for certain event contexts + /// + protected BaseValidatingTicketContext(HttpContext context, TOptions options, AuthenticationTicket ticket) : base(context, options) + { + Ticket = ticket; + } + + /// + /// Contains the identity and properties for the application to authenticate. If the Validated method + /// is invoked with an AuthenticationTicket or ClaimsIdentity argument, that new value is assigned to + /// this property in addition to changing IsValidated to true. + /// + public AuthenticationTicket Ticket { get; private set; } + + /// + /// Replaces the ticket information on this context and marks it as as validated by the application. + /// IsValidated becomes true and HasError becomes false as a result of calling. + /// + /// Assigned to the Ticket property + /// True if the validation has taken effect. + public bool Validated(AuthenticationTicket ticket) + { + Ticket = ticket; + return Validated(); + } + + /// + /// Alters the ticket information on this context and marks it as as validated by the application. + /// IsValidated becomes true and HasError becomes false as a result of calling. + /// + /// Assigned to the Ticket.Identity property + /// True if the validation has taken effect. + public bool Validated(ClaimsPrincipal principal) + { + AuthenticationProperties properties = Ticket != null ? Ticket.Properties : new AuthenticationProperties(); + return Validated(new AuthenticationTicket(principal, properties, Options.AuthenticationScheme)); + } + } + +} diff --git a/Yavsc/Auth/AuthServer/DefaultBehavior.cs b/Yavsc/Auth/AuthServer/DefaultBehavior.cs new file mode 100644 index 00000000..9a32a2f8 --- /dev/null +++ b/Yavsc/Auth/AuthServer/DefaultBehavior.cs @@ -0,0 +1,40 @@ +using System; +using System.Threading.Tasks; + +namespace OAuth.AspNet.AuthServer +{ + + internal static class DefaultBehavior + { + internal static readonly Func ValidateAuthorizeRequest = context => + { + context.Validated(); + return Task.FromResult(null); + }; + + internal static readonly Func ValidateTokenRequest = context => + { + context.Validated(); + return Task.FromResult(null); + }; + + internal static readonly Func GrantAuthorizationCode = context => + { + if (context.Ticket != null && context.Ticket.Principal != null && context.Ticket.Principal.Identity.IsAuthenticated) + { + context.Validated(); + } + return Task.FromResult(null); + }; + + internal static readonly Func GrantRefreshToken = context => + { + if (context.Ticket != null && context.Ticket.Principal != null && context.Ticket.Principal.Identity.IsAuthenticated) + { + context.Validated(); + } + return Task.FromResult(null); + }; + } + +} diff --git a/Yavsc/Auth/AuthServer/IApplicationStore.cs b/Yavsc/Auth/AuthServer/IApplicationStore.cs new file mode 100644 index 00000000..67602d59 --- /dev/null +++ b/Yavsc/Auth/AuthServer/IApplicationStore.cs @@ -0,0 +1,14 @@ + +public interface IApplication +{ + string ApplicationID { get; set; } + string DisplayName { get; set; } + string RedirectUri { get; set; } + string LogoutRedirectUri { get; set; } + string Secret { get; set; } +} +public interface IApplicationStore +{ + IApplication FindApplication(string clientId); + +} \ No newline at end of file diff --git a/Yavsc/Auth/AuthServer/IAuthenticationTokenProvider.cs b/Yavsc/Auth/AuthServer/IAuthenticationTokenProvider.cs new file mode 100644 index 00000000..9d66467c --- /dev/null +++ b/Yavsc/Auth/AuthServer/IAuthenticationTokenProvider.cs @@ -0,0 +1,14 @@ +using System.Threading.Tasks; + +namespace OAuth.AspNet.AuthServer +{ + + public interface IAuthenticationTokenProvider + { + void Create(AuthenticationTokenCreateContext context); + Task CreateAsync(AuthenticationTokenCreateContext context); + void Receive(AuthenticationTokenReceiveContext context); + Task ReceiveAsync(AuthenticationTokenReceiveContext context); + } + +} diff --git a/Yavsc/Auth/AuthServer/IOAuthAuthorizationServerProvider.cs b/Yavsc/Auth/AuthServer/IOAuthAuthorizationServerProvider.cs new file mode 100644 index 00000000..57f919c6 --- /dev/null +++ b/Yavsc/Auth/AuthServer/IOAuthAuthorizationServerProvider.cs @@ -0,0 +1,172 @@ +using System.Threading.Tasks; + +namespace OAuth.AspNet.AuthServer +{ + + /// + /// Interface for OAuthAuthorizationServerOptions.Provider property used by Authorization + /// Server to communicate with the web application while processing requests. + /// + public interface IOAuthAuthorizationServerProvider + { + /// + /// Called to determine if an incoming request is treated as an Authorize or Token + /// endpoint. If Options.AuthorizeEndpointPath or Options.TokenEndpointPath + /// are assigned values, then handling this event is optional and context.IsAuthorizeEndpoint and context.IsTokenEndpoint + /// will already be true if the request path matches. + /// + /// The context of the event carries information in and results out. + /// Task to enable asynchronous execution + Task MatchEndpoint(OAuthMatchContext context); + + /// + /// Called to validate that the context.ClientId is a registered "client_id", and that the context.RedirectUri a "redirect_uri" + /// registered for that client. This only occurs when processing the Authorize endpoint. The application MUST implement this + /// call, and it MUST validate both of those factors before calling context.Validated. If the context.Validated method is called + /// with a given redirectUri parameter, then IsValidated will only become true if the incoming redirect URI matches the given redirect URI. + /// If context.Validated is not called the request will not proceed further. + /// + /// The context of the event carries information in and results out. + /// Task to enable asynchronous execution + Task ValidateClientRedirectUri(OAuthValidateClientRedirectUriContext context); + + /// + /// Called to validate that the origin of the request is a registered "client_id", and that the correct credentials for that client are + /// present on the request. If the web application accepts Basic authentication credentials, + /// context.TryGetBasicCredentials(out clientId, out clientSecret) may be called to acquire those values if present in the request header. If the web + /// application accepts "client_id" and "client_secret" as form encoded POST parameters, + /// context.TryGetFormCredentials(out clientId, out clientSecret) may be called to acquire those values if present in the request body. + /// If context.Validated is not called the request will not proceed further. + /// + /// The context of the event carries information in and results out. + /// Task to enable asynchronous execution + Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context); + + /// + /// Called for each request to the Authorize endpoint to determine if the request is valid and should continue. + /// The default behavior when using the OAuthAuthorizationServerProvider is to assume well-formed requests, with + /// validated client redirect URI, should continue processing. An application may add any additional constraints. + /// + /// The context of the event carries information in and results out. + /// Task to enable asynchronous execution + Task ValidateAuthorizeRequest(OAuthValidateAuthorizeRequestContext context); + + /// + /// Called for each request to the Token endpoint to determine if the request is valid and should continue. + /// The default behavior when using the OAuthAuthorizationServerProvider is to assume well-formed requests, with + /// validated client credentials, should continue processing. An application may add any additional constraints. + /// + /// The context of the event carries information in and results out. + /// Task to enable asynchronous execution + Task ValidateTokenRequest(OAuthValidateTokenRequestContext context); + + /// + /// Called when a request to the Token endpoint arrives with a "grant_type" of "authorization_code". This occurs after the Authorize + /// endpoint as redirected the user-agent back to the client with a "code" parameter, and the client is exchanging that for an "access_token". + /// The claims and properties + /// associated with the authorization code are present in the context.Ticket. The application must call context.Validated to instruct the Authorization + /// Server middleware to issue an access token based on those claims and properties. The call to context.Validated may be given a different + /// AuthenticationTicket or ClaimsIdentity in order to control which information flows from authorization code to access token. + /// The default behavior when using the OAuthAuthorizationServerProvider is to flow information from the authorization code to + /// the access token unmodified. + /// See also http://tools.ietf.org/html/rfc6749#section-4.1.3 + /// + /// The context of the event carries information in and results out. + /// Task to enable asynchronous execution + Task GrantAuthorizationCode(OAuthGrantAuthorizationCodeContext context); + + /// + /// Called when a request to the Token endpoint arrives with a "grant_type" of "refresh_token". This occurs if your application has issued a "refresh_token" + /// along with the "access_token", and the client is attempting to use the "refresh_token" to acquire a new "access_token", and possibly a new "refresh_token". + /// To issue a refresh token the an Options.RefreshTokenProvider must be assigned to create the value which is returned. The claims and properties + /// associated with the refresh token are present in the context.Ticket. The application must call context.Validated to instruct the + /// Authorization Server middleware to issue an access token based on those claims and properties. The call to context.Validated may + /// be given a different AuthenticationTicket or ClaimsIdentity in order to control which information flows from the refresh token to + /// the access token. The default behavior when using the OAuthAuthorizationServerProvider is to flow information from the refresh token to + /// the access token unmodified. + /// See also http://tools.ietf.org/html/rfc6749#section-6 + /// + /// The context of the event carries information in and results out. + /// Task to enable asynchronous execution + Task GrantRefreshToken(OAuthGrantRefreshTokenContext context); + + /// + /// Called when a request to the Token endpoint arrives with a "grant_type" of "password". This occurs when the user has provided name and password + /// credentials directly into the client application's user interface, and the client application is using those to acquire an "access_token" and + /// optional "refresh_token". If the web application supports the + /// resource owner credentials grant type it must validate the context.Username and context.Password as appropriate. To issue an + /// access token the context.Validated must be called with a new ticket containing the claims about the resource owner which should be associated + /// with the access token. The application should take appropriate measures to ensure that the endpoint isn’t abused by malicious callers. . + /// The default behavior is to reject this grant type. + /// See also http://tools.ietf.org/html/rfc6749#section-4.3.2 + /// + /// The context of the event carries information in and results out. + /// Task to enable asynchronous execution + Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context); + + /// + /// Called when a request to the Token endpoint arrives with a "grant_type" of "client_credentials". This occurs when a registered client + /// application wishes to acquire an "access_token" to interact with protected resources on it's own behalf, rather than on behalf of an authenticated user. + /// If the web application supports the client credentials it may assume the context.ClientId has been validated by the ValidateClientAuthentication call. + /// To issue an access token the context.Validated must be called with a new ticket containing the claims about the client application which should be associated + /// with the access token. The application should take appropriate measures to ensure that the endpoint isn’t abused by malicious callers. + /// The default behavior is to reject this grant type. + /// See also http://tools.ietf.org/html/rfc6749#section-4.4.2 + /// + /// The context of the event carries information in and results out. + /// Task to enable asynchronous execution + Task GrantClientCredentials(OAuthGrantClientCredentialsContext context); + + /// + /// Called when a request to the Token andpoint arrives with a "grant_type" of any other value. If the application supports custom grant types + /// it is entirely responsible for determining if the request should result in an access_token. If context.Validated is called with ticket + /// information the response body is produced in the same way as the other standard grant types. If additional response parameters must be + /// included they may be added in the final TokenEndpoint call. + /// See also http://tools.ietf.org/html/rfc6749#section-4.5 + /// + /// The context of the event carries information in and results out. + /// Task to enable asynchronous execution + Task GrantCustomExtension(OAuthGrantCustomExtensionContext context); + + /// + /// Called at the final stage of an incoming Authorize endpoint request before the execution continues on to the web application component + /// responsible for producing the html response. Anything present in the OWIN pipeline following the Authorization Server may produce the + /// response for the Authorize page. If running on IIS any ASP.NET technology running on the server may produce the response for the + /// Authorize page. If the web application wishes to produce the response directly in the AuthorizeEndpoint call it may write to the + /// context.Response directly and should call context.RequestCompleted to stop other handlers from executing. If the web application wishes + /// to grant the authorization directly in the AuthorizeEndpoint call it cay call context.OwinContext.Authentication.SignIn with the + /// appropriate ClaimsIdentity and should call context.RequestCompleted to stop other handlers from executing. + /// + /// The context of the event carries information in and results out. + /// Task to enable asynchronous execution + Task AuthorizeEndpoint(OAuthAuthorizeEndpointContext context); + + /// + /// Called at the final stage of a successful Token endpoint request. An application may implement this call in order to do any final + /// modification of the claims being used to issue access or refresh tokens. This call may also be used in order to add additional + /// response parameters to the Token endpoint's json response body. + /// + /// The context of the event carries information in and results out. + /// Task to enable asynchronous execution + Task TokenEndpoint(OAuthTokenEndpointContext context); + + /// + /// Called before the AuthorizationEndpoint redirects its response to the caller. The response could be the + /// token, when using implicit flow or the AuthorizationEndpoint when using authorization code flow. + /// An application may implement this call in order to do any final modification of the claims being used + /// to issue access or refresh tokens. This call may also be used in order to add additional + /// response parameters to the authorization endpoint's response. + /// + /// The context of the event carries information in and results out. + /// Task to enable asynchronous execution + Task AuthorizationEndpointResponse(OAuthAuthorizationEndpointResponseContext context); + + /// + /// Called before the TokenEndpoint redirects its response to the caller. + /// + /// + /// + Task TokenEndpointResponse(OAuthTokenEndpointResponseContext context); + } + +} diff --git a/Yavsc/Auth/AuthServer/OAuthAuthorizationServerHandler.cs b/Yavsc/Auth/AuthServer/OAuthAuthorizationServerHandler.cs new file mode 100644 index 00000000..8aa3b8f5 --- /dev/null +++ b/Yavsc/Auth/AuthServer/OAuthAuthorizationServerHandler.cs @@ -0,0 +1,816 @@ +using Microsoft.AspNet.Authentication; +using Microsoft.AspNet.Http; +using Microsoft.AspNet.Http.Authentication; +using Microsoft.AspNet.Http.Features.Authentication; +using Microsoft.AspNet.WebUtilities; +using Microsoft.Extensions.Logging; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Text; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; + +namespace OAuth.AspNet.AuthServer +{ + + public class OAuthAuthorizationServerHandler : AuthenticationHandler + { + public OAuthAuthorizationServerHandler(IApplicationStore applicationStore) + { + ApplicationStore = applicationStore; + } + IServiceScope serviceScope; + + public IApplicationStore ApplicationStore { get; private set;} + #region non-Public Members + + private AuthorizeEndpointRequest _authorizeEndpointRequest; + + private OAuthValidateClientRedirectUriContext _clientContext; + + private Task SendErrorAsJsonAsync(BaseValidatingContext validatingContext) + { + string error = validatingContext.HasError ? validatingContext.Error : Constants.Errors.InvalidRequest; + string errorDescription = validatingContext.HasError ? validatingContext.ErrorDescription : null; + string errorUri = validatingContext.HasError ? validatingContext.ErrorUri : null; + + string body; + + MemoryStream stream, memoryStream = null; + + StreamWriter streamWriter = null; + + try + { + stream = memoryStream = new MemoryStream(); + + streamWriter = new StreamWriter(memoryStream); + + using (var writer = new JsonTextWriter(streamWriter)) + { + memoryStream = null; + + streamWriter = null; + + writer.WriteStartObject(); + writer.WritePropertyName(Constants.Parameters.Error); + writer.WriteValue(error); + if (!string.IsNullOrEmpty(errorDescription)) + { + writer.WritePropertyName(Constants.Parameters.ErrorDescription); + writer.WriteValue(errorDescription); + } + if (!string.IsNullOrEmpty(errorUri)) + { + writer.WritePropertyName(Constants.Parameters.ErrorUri); + writer.WriteValue(errorUri); + } + writer.WriteEndObject(); + writer.Flush(); + body = Encoding.UTF8.GetString(stream.ToArray()); + } + } + finally + { + if (memoryStream != null) + memoryStream.Dispose(); + } + + Response.StatusCode = 400; + Response.ContentType = "application/json;charset=UTF-8"; + Response.Headers["Cache-Control"] = "no-cache"; + Response.Headers["Pragma"] = "no-cache"; + Response.Headers["Expires"] = "-1"; + Response.Headers["Content-Length"] = body.Length.ToString(CultureInfo.InvariantCulture); + return Response.WriteAsync(body, Context.RequestAborted); + } + + private async Task SendErrorPageAsync(string error, string errorDescription, string errorUri) + { + Response.StatusCode = 400; + Response.Headers["Cache-Control"] = "no-cache"; + Response.Headers["Pragma"] = "no-cache"; + Response.Headers["Expires"] = "-1"; + + if (Options.ApplicationCanDisplayErrors) + { + Context.Items["oauth.Error"] = error; + Context.Items["oauth.ErrorDescription"] = errorDescription; + Context.Items["oauth.ErrorUri"] = errorUri; + + // request is not handled - pass through to application for rendering + return false; + } + + var memory = new MemoryStream(); + string body; + using (var writer = new StreamWriter(memory)) + { + writer.WriteLine("error: {0}", error); + if (!string.IsNullOrEmpty(errorDescription)) + { + writer.WriteLine("error_description: {0}", errorDescription); + } + if (!string.IsNullOrEmpty(errorUri)) + { + writer.WriteLine("error_uri: {0}", errorUri); + } + writer.Flush(); + body = Encoding.UTF8.GetString(memory.ToArray()); + } + + Response.ContentType = "text/plain;charset=UTF-8"; + Response.Headers["Content-Length"] = body.Length.ToString(CultureInfo.InvariantCulture); + await Response.WriteAsync(body, Context.RequestAborted); + // request is handled, does not pass on to application + return true; + } + + private Task SendErrorRedirectAsync(OAuthValidateClientRedirectUriContext clientContext, BaseValidatingContext validatingContext) + { + if (clientContext == null) + { + throw new ArgumentNullException("clientContext"); + } + + string error = validatingContext.HasError ? validatingContext.Error : Constants.Errors.InvalidRequest; + string errorDescription = validatingContext.HasError ? validatingContext.ErrorDescription : null; + string errorUri = validatingContext.HasError ? validatingContext.ErrorUri : null; + + if (!clientContext.IsValidated) + { + // write error in response body if client_id or redirect_uri have not been validated + return SendErrorPageAsync(error, errorDescription, errorUri); + } + + // redirect with error if client_id and redirect_uri have been validated + string location = QueryHelpers.AddQueryString(clientContext.RedirectUri, Constants.Parameters.Error, error); + if (!string.IsNullOrEmpty(errorDescription)) + { + location = QueryHelpers.AddQueryString(location, Constants.Parameters.ErrorDescription, errorDescription); + } + if (!string.IsNullOrEmpty(errorUri)) + { + location = QueryHelpers.AddQueryString(location, Constants.Parameters.ErrorUri, errorUri); + } + Response.Redirect(location); + // request is handled, does not pass on to application + return Task.FromResult(true); + } + + private static AuthenticationTicket ReturnOutcome(OAuthValidateTokenRequestContext validatingContext, BaseValidatingContext grantContext, AuthenticationTicket ticket, string defaultError) + { + if (!validatingContext.IsValidated) + return null; + + if (!grantContext.IsValidated) + { + if (grantContext.HasError) + { + validatingContext.SetError(grantContext.Error, grantContext.ErrorDescription, grantContext.ErrorUri); + } + else + { + validatingContext.SetError(defaultError); + } + + return null; + } + + if (ticket == null) + { + validatingContext.SetError(defaultError); + return null; + } + + return ticket; + } + + private async Task InvokeTokenEndpointAuthorizationCodeGrantAsync(OAuthValidateTokenRequestContext validatingContext, DateTimeOffset currentUtc) + { + TokenEndpointRequest tokenEndpointRequest = validatingContext.TokenRequest; + + var authorizationCodeContext = new AuthenticationTokenReceiveContext(Context, Options.AuthorizationCodeFormat, tokenEndpointRequest.AuthorizationCodeGrant.Code); + + await Options.AuthorizationCodeProvider.ReceiveAsync(authorizationCodeContext); + + AuthenticationTicket ticket = authorizationCodeContext.Ticket; + + if (ticket == null) + { + Logger.LogError("invalid authorization code"); + validatingContext.SetError(Constants.Errors.InvalidGrant); + return null; + } + + if (!ticket.Properties.ExpiresUtc.HasValue || + ticket.Properties.ExpiresUtc < currentUtc) + { + Logger.LogError("expired authorization code"); + validatingContext.SetError(Constants.Errors.InvalidGrant); + return null; + } + + string clientId; + if (!ticket.Properties.Items.TryGetValue(Constants.Extra.ClientId, out clientId) || + !string.Equals(clientId, validatingContext.ClientContext.ClientId, StringComparison.Ordinal)) + { + Logger.LogError("authorization code does not contain matching client_id"); + validatingContext.SetError(Constants.Errors.InvalidGrant); + return null; + } + + string redirectUri; + if (ticket.Properties.Items.TryGetValue(Constants.Extra.RedirectUri, out redirectUri)) + { + ticket.Properties.Items.Remove(Constants.Extra.RedirectUri); + if (!string.Equals(redirectUri, tokenEndpointRequest.AuthorizationCodeGrant.RedirectUri, StringComparison.Ordinal)) + { + Logger.LogError("authorization code does not contain matching redirect_uri"); + validatingContext.SetError(Constants.Errors.InvalidGrant); + return null; + } + } + + await Options.Provider.ValidateTokenRequest(validatingContext); + + var grantContext = new OAuthGrantAuthorizationCodeContext( + Context, Options, ticket); + + if (validatingContext.IsValidated) + { + await Options.Provider.GrantAuthorizationCode(grantContext); + } + + return ReturnOutcome(validatingContext, grantContext, grantContext.Ticket, Constants.Errors.InvalidGrant); + } + + private async Task InvokeTokenEndpointResourceOwnerPasswordCredentialsGrantAsync(OAuthValidateTokenRequestContext validatingContext, DateTimeOffset currentUtc) + { + TokenEndpointRequest tokenEndpointRequest = validatingContext.TokenRequest; + + await Options.Provider.ValidateTokenRequest(validatingContext); + + var grantContext = new OAuthGrantResourceOwnerCredentialsContext( + Context, + Options, + validatingContext.ClientContext.ClientId, + tokenEndpointRequest.ResourceOwnerPasswordCredentialsGrant.UserName, + tokenEndpointRequest.ResourceOwnerPasswordCredentialsGrant.Password, + tokenEndpointRequest.ResourceOwnerPasswordCredentialsGrant.Scope + ); + + if (validatingContext.IsValidated) + await Options.Provider.GrantResourceOwnerCredentials(grantContext); + + return ReturnOutcome(validatingContext, grantContext, grantContext.Ticket, Constants.Errors.InvalidGrant); + } + + private async Task InvokeTokenEndpointClientCredentialsGrantAsync(OAuthValidateTokenRequestContext validatingContext, DateTimeOffset currentUtc) + { + TokenEndpointRequest tokenEndpointRequest = validatingContext.TokenRequest; + + await Options.Provider.ValidateTokenRequest(validatingContext); + + if (!validatingContext.IsValidated) + return null; + + var grantContext = new OAuthGrantClientCredentialsContext(Context, Options, validatingContext.ClientContext.ClientId, tokenEndpointRequest.ClientCredentialsGrant.Scope); + + await Options.Provider.GrantClientCredentials(grantContext); + + return ReturnOutcome(validatingContext, grantContext, grantContext.Ticket, Constants.Errors.UnauthorizedClient); + } + + private async Task InvokeTokenEndpointRefreshTokenGrantAsync(OAuthValidateTokenRequestContext validatingContext, DateTimeOffset currentUtc) + { + TokenEndpointRequest tokenEndpointRequest = validatingContext.TokenRequest; + + var refreshTokenContext = new AuthenticationTokenReceiveContext(Context, Options.RefreshTokenFormat, tokenEndpointRequest.RefreshTokenGrant.RefreshToken); + + await Options.RefreshTokenProvider.ReceiveAsync(refreshTokenContext); + + AuthenticationTicket ticket = refreshTokenContext.Ticket; + + if (ticket == null) + { + Logger.LogError("invalid refresh token"); + validatingContext.SetError(Constants.Errors.InvalidGrant); + return null; + } + + if (!ticket.Properties.ExpiresUtc.HasValue || ticket.Properties.ExpiresUtc < currentUtc) + { + Logger.LogError("expired refresh token"); + validatingContext.SetError(Constants.Errors.InvalidGrant); + return null; + } + + await Options.Provider.ValidateTokenRequest(validatingContext); + + var grantContext = new OAuthGrantRefreshTokenContext(Context, Options, ticket, validatingContext.ClientContext.ClientId); + + if (validatingContext.IsValidated) + await Options.Provider.GrantRefreshToken(grantContext); + + return ReturnOutcome(validatingContext, grantContext, grantContext.Ticket, Constants.Errors.InvalidGrant); + } + + private async Task InvokeTokenEndpointCustomGrantAsync(OAuthValidateTokenRequestContext validatingContext, DateTimeOffset currentUtc) + { + TokenEndpointRequest tokenEndpointRequest = validatingContext.TokenRequest; + + await Options.Provider.ValidateTokenRequest(validatingContext); + + var grantContext = new OAuthGrantCustomExtensionContext(Context, Options, validatingContext.ClientContext.ClientId, tokenEndpointRequest.GrantType, tokenEndpointRequest.CustomExtensionGrant.Parameters); + + if (validatingContext.IsValidated) + await Options.Provider.GrantCustomExtension(grantContext); + + return ReturnOutcome(validatingContext, grantContext, grantContext.Ticket, Constants.Errors.UnsupportedGrantType); + } + + private async Task InvokeAuthorizeEndpointAsync() + { + var authorizeRequest = new AuthorizeEndpointRequest(Request.Query); + + var clientContext = new OAuthValidateClientRedirectUriContext(ApplicationStore,Context, Options, authorizeRequest.ClientId, authorizeRequest.RedirectUri); + + if (!string.IsNullOrEmpty(authorizeRequest.RedirectUri)) + { + bool acceptableUri = true; + + Uri validatingUri; + + if (!Uri.TryCreate(authorizeRequest.RedirectUri, UriKind.Absolute, out validatingUri)) + { + // The redirection endpoint URI MUST be an absolute URI + // http://tools.ietf.org/html/rfc6749#section-3.1.2 + acceptableUri = false; + } + else if (!string.IsNullOrEmpty(validatingUri.Fragment)) + { + // The endpoint URI MUST NOT include a fragment component. + // http://tools.ietf.org/html/rfc6749#section-3.1.2 + acceptableUri = false; + } + else if (!Options.AllowInsecureHttp && string.Equals(validatingUri.Scheme, "http", StringComparison.OrdinalIgnoreCase)) + { + // The redirection endpoint SHOULD require the use of TLS + // http://tools.ietf.org/html/rfc6749#section-3.1.2.1 + acceptableUri = false; + } + if (!acceptableUri) + { + clientContext.SetError(Constants.Errors.InvalidRequest); + + return await SendErrorRedirectAsync(clientContext, clientContext); + } + } + + await Options.Provider.ValidateClientRedirectUri(clientContext); + + if (!clientContext.IsValidated) + { + Logger.LogVerbose("Unable to validate client information"); + + return await SendErrorRedirectAsync(clientContext, clientContext); + } + + var validatingContext = new OAuthValidateAuthorizeRequestContext(Context, Options, authorizeRequest, clientContext); + + if (string.IsNullOrEmpty(authorizeRequest.ResponseType)) + { + Logger.LogVerbose("Authorize endpoint request missing required response_type parameter"); + + validatingContext.SetError(Constants.Errors.InvalidRequest); + } + else if (!authorizeRequest.IsAuthorizationCodeGrantType && !authorizeRequest.IsImplicitGrantType) + { + Logger.LogVerbose("Authorize endpoint request contains unsupported response_type parameter"); + + validatingContext.SetError(Constants.Errors.UnsupportedResponseType); + } + else + { + await Options.Provider.ValidateAuthorizeRequest(validatingContext); + } + + if (!validatingContext.IsValidated) + { + // an invalid request is not processed further + return await SendErrorRedirectAsync(clientContext, validatingContext); + } + + _clientContext = clientContext; + + _authorizeEndpointRequest = authorizeRequest; + + var authorizeEndpointContext = new OAuthAuthorizeEndpointContext(Context, Options, authorizeRequest); + + await Options.Provider.AuthorizeEndpoint(authorizeEndpointContext); + + return authorizeEndpointContext.IsRequestCompleted; + } + + private async Task InvokeTokenEndpointAsync() + { + DateTimeOffset currentUtc = Options.SystemClock.UtcNow; + + // remove milliseconds in case they don't round-trip + currentUtc = currentUtc.Subtract(TimeSpan.FromMilliseconds(currentUtc.Millisecond)); + + IFormCollection form = await Request.ReadFormAsync(); + + var clientContext = new OAuthValidateClientAuthenticationContext(Context, Options, form, ApplicationStore); + + await Options.Provider.ValidateClientAuthentication(clientContext); + + if (!clientContext.IsValidated) + { + Logger.LogError("clientID is not valid."); + + if (!clientContext.HasError) + clientContext.SetError(Constants.Errors.InvalidClient); + + await SendErrorAsJsonAsync(clientContext); + + return; + } + + var tokenEndpointRequest = new TokenEndpointRequest(form); + + var validatingContext = new OAuthValidateTokenRequestContext(Context, Options, tokenEndpointRequest, clientContext); + + AuthenticationTicket ticket = null; + if (tokenEndpointRequest.IsAuthorizationCodeGrantType) + { + // Authorization Code Grant http://tools.ietf.org/html/rfc6749#section-4.1 + // Access Token Request http://tools.ietf.org/html/rfc6749#section-4.1.3 + ticket = await InvokeTokenEndpointAuthorizationCodeGrantAsync(validatingContext, currentUtc); + } + else if (tokenEndpointRequest.IsResourceOwnerPasswordCredentialsGrantType) + { + // Resource Owner Password Credentials Grant http://tools.ietf.org/html/rfc6749#section-4.3 + // Access Token Request http://tools.ietf.org/html/rfc6749#section-4.3.2 + ticket = await InvokeTokenEndpointResourceOwnerPasswordCredentialsGrantAsync(validatingContext, currentUtc); + } + else if (tokenEndpointRequest.IsClientCredentialsGrantType) + { + // Client Credentials Grant http://tools.ietf.org/html/rfc6749#section-4.4 + // Access Token Request http://tools.ietf.org/html/rfc6749#section-4.4.2 + ticket = await InvokeTokenEndpointClientCredentialsGrantAsync(validatingContext, currentUtc); + } + else if (tokenEndpointRequest.IsRefreshTokenGrantType) + { + // Refreshing an Access Token + // http://tools.ietf.org/html/rfc6749#section-6 + ticket = await InvokeTokenEndpointRefreshTokenGrantAsync(validatingContext, currentUtc); + } + else if (tokenEndpointRequest.IsCustomExtensionGrantType) + { + // Defining New Authorization Grant Types + // http://tools.ietf.org/html/rfc6749#section-8.3 + ticket = await InvokeTokenEndpointCustomGrantAsync(validatingContext, currentUtc); + } + else + { + // Error Response http://tools.ietf.org/html/rfc6749#section-5.2 + // The authorization grant type is not supported by the + // authorization server. + Logger.LogError("grant type is not recognized"); + + validatingContext.SetError(Constants.Errors.UnsupportedGrantType); + } + + if (ticket == null) + { + await SendErrorAsJsonAsync(validatingContext); + return; + } + + ticket.Properties.IssuedUtc = currentUtc; + ticket.Properties.ExpiresUtc = currentUtc.Add(Options.AccessTokenExpireTimeSpan); + + var tokenEndpointContext = new OAuthTokenEndpointContext(Context, Options, ticket, tokenEndpointRequest); + + await Options.Provider.TokenEndpoint(tokenEndpointContext); + + if (tokenEndpointContext.TokenIssued) + { + ticket = new AuthenticationTicket(tokenEndpointContext.Principal, tokenEndpointContext.Properties, tokenEndpointContext.Options.AuthenticationScheme); + } + else + { + Logger.LogError("Token was not issued to tokenEndpointContext"); + validatingContext.SetError(Constants.Errors.InvalidGrant); + await SendErrorAsJsonAsync(validatingContext); + return; + } + + var accessTokenContext = new AuthenticationTokenCreateContext( + Context, + Options.AccessTokenFormat, + ticket); + + await Options.AccessTokenProvider.CreateAsync(accessTokenContext); + + string accessToken = accessTokenContext.Token; + if (string.IsNullOrEmpty(accessToken)) + { + accessToken = accessTokenContext.SerializeTicket(); + } + + DateTimeOffset? accessTokenExpiresUtc = ticket.Properties.ExpiresUtc; + + var refreshTokenCreateContext = new AuthenticationTokenCreateContext(Context, Options.RefreshTokenFormat, accessTokenContext.Ticket); + + await Options.RefreshTokenProvider.CreateAsync(refreshTokenCreateContext); + + string refreshToken = refreshTokenCreateContext.Token; + + var tokenEndpointResponseContext = new OAuthTokenEndpointResponseContext(Context, Options, ticket, tokenEndpointRequest, accessToken, tokenEndpointContext.AdditionalResponseParameters); + + await Options.Provider.TokenEndpointResponse(tokenEndpointResponseContext); + + MemoryStream stream, memoryStream = null; + + string body; + + try + { + stream = memoryStream = new MemoryStream(); + + using (var writer = new JsonTextWriter(new StreamWriter(memoryStream))) + { + memoryStream = null; + + writer.WriteStartObject(); + writer.WritePropertyName(Constants.Parameters.AccessToken); + writer.WriteValue(accessToken); + writer.WritePropertyName(Constants.Parameters.TokenType); + writer.WriteValue(Constants.TokenTypes.Bearer); + + if (accessTokenExpiresUtc.HasValue) + { + TimeSpan? expiresTimeSpan = accessTokenExpiresUtc - currentUtc; + var expiresIn = (long)expiresTimeSpan.Value.TotalSeconds; + if (expiresIn > 0) + { + writer.WritePropertyName(Constants.Parameters.ExpiresIn); + writer.WriteValue(expiresIn); + } + } + + if (!string.IsNullOrEmpty(refreshToken)) + { + writer.WritePropertyName(Constants.Parameters.RefreshToken); + writer.WriteValue(refreshToken); + } + + foreach (var additionalResponseParameter in tokenEndpointResponseContext.AdditionalResponseParameters) + { + writer.WritePropertyName(additionalResponseParameter.Key); + writer.WriteValue(additionalResponseParameter.Value); + } + + writer.WriteEndObject(); + writer.Flush(); + body = Encoding.UTF8.GetString(stream.ToArray()); + + Response.ContentType = "application/json;charset=UTF-8"; + Response.Headers["Cache-Control"] = "no-cache"; + Response.Headers["Pragma"] = "no-cache"; + Response.Headers["Expires"] = "-1"; + Response.ContentLength = Encoding.UTF8.GetByteCount(body); + } + } + finally + { + if (memoryStream != null) + memoryStream.Dispose(); + } + + await Response.WriteAsync(body, Encoding.UTF8, Context.RequestAborted); + } + + private class Appender + { + private readonly char _delimiter; + private readonly StringBuilder _sb; + private bool _hasDelimiter; + + public Appender(string value, char delimiter) + { + _sb = new StringBuilder(value); + _delimiter = delimiter; + _hasDelimiter = value.IndexOf(delimiter) != -1; + } + + public Appender Append(string name, string value) + { + _sb.Append(_hasDelimiter ? '&' : _delimiter) + .Append(Uri.EscapeDataString(name)) + .Append('=') + .Append(Uri.EscapeDataString(value)); + + _hasDelimiter = true; + + return this; + } + + public override string ToString() + { + return _sb.ToString(); + } + } + + + protected override Task HandleAuthenticateAsync() + { + return Task.FromResult(null); + } + + #endregion + + #region Public Members + + public override async Task HandleRequestAsync() + { + var matchRequestContext = new OAuthMatchContext(Context, Options); + + if (Options.AuthorizeEndpointPath.HasValue && Options.AuthorizeEndpointPath == Request.Path) + { + matchRequestContext.MatchesAuthorizeEndpoint(); + } + else if (Options.TokenEndpointPath.HasValue && Options.TokenEndpointPath == Request.Path) + { + matchRequestContext.MatchesTokenEndpoint(); + } + + await Options.Provider.MatchEndpoint(matchRequestContext); + + if (matchRequestContext.HandledResponse) + return true; + + if (matchRequestContext.Skipped) + return false; + + if (matchRequestContext.IsAuthorizeEndpoint || matchRequestContext.IsTokenEndpoint) + { + if (!Options.AllowInsecureHttp && !Context.Request.IsHttps) + { + Logger.LogWarning("Authorization server ignoring http request because AllowInsecureHttp is false."); + + return false; + } + + if (matchRequestContext.IsAuthorizeEndpoint) + return await InvokeAuthorizeEndpointAsync(); + + if (matchRequestContext.IsTokenEndpoint) + { + await InvokeTokenEndpointAsync(); + + return true; + } + } + + return false; + } + + protected override async Task HandleSignInAsync(SignInContext context) + { + // only successful results of an authorize request are altered + if (_clientContext == null || _authorizeEndpointRequest == null || Response.StatusCode != 200) + return; + + if (context?.Principal == null) + return; + + AuthenticationResponseGrant signin = new AuthenticationResponseGrant(context.Principal, new AuthenticationProperties(context.Properties)); + + var returnParameter = new Dictionary(); + + if (_authorizeEndpointRequest.IsAuthorizationCodeGrantType) + { + DateTimeOffset currentUtc = Options.SystemClock.UtcNow; + signin.Properties.IssuedUtc = currentUtc; + signin.Properties.ExpiresUtc = currentUtc.Add(Options.AuthorizationCodeExpireTimeSpan); + + // associate client_id with all subsequent tickets + signin.Properties.Items[Constants.Extra.ClientId] = _authorizeEndpointRequest.ClientId; + if (!string.IsNullOrEmpty(_authorizeEndpointRequest.RedirectUri)) + { + // keep original request parameter for later comparison + signin.Properties.Items[Constants.Extra.RedirectUri] = _authorizeEndpointRequest.RedirectUri; + } + + var tokenCreationContext = new AuthenticationTokenCreateContext(Context, Options.AuthorizationCodeFormat, new AuthenticationTicket(signin.Principal, signin.Properties, signin.Identity.AuthenticationType)); + + await Options.AuthorizationCodeProvider.CreateAsync(tokenCreationContext); + + string code = tokenCreationContext.Token; + if (string.IsNullOrEmpty(code)) + { + Logger.LogError("response_type code requires an Options.AuthorizationCodeProvider implementing a single-use token."); + var errorContext = new OAuthValidateAuthorizeRequestContext(Context, Options, _authorizeEndpointRequest, _clientContext); + errorContext.SetError(Constants.Errors.UnsupportedResponseType); + await SendErrorRedirectAsync(_clientContext, errorContext); + return; + } + + var authResponseContext = new OAuthAuthorizationEndpointResponseContext(Context, Options, new AuthenticationTicket(signin.Principal, signin.Properties, signin.Identity.AuthenticationType), _authorizeEndpointRequest, null, code); + + await Options.Provider.AuthorizationEndpointResponse(authResponseContext); + + foreach (var parameter in authResponseContext.AdditionalResponseParameters) + { + returnParameter[parameter.Key] = parameter.Value.ToString(); + } + + returnParameter[Constants.Parameters.Code] = code; + + if (!string.IsNullOrEmpty(_authorizeEndpointRequest.State)) + { + returnParameter[Constants.Parameters.State] = _authorizeEndpointRequest.State; + } + + string location = string.Empty; + if (_authorizeEndpointRequest.IsFormPostResponseMode) + { + location = Options.FormPostEndpoint.ToString(); + returnParameter[Constants.Parameters.RedirectUri] = _clientContext.RedirectUri; + } + else + { + location = _clientContext.RedirectUri; + } + + foreach (var key in returnParameter.Keys) + { + location = QueryHelpers.AddQueryString(location, key, returnParameter[key]); + } + + Response.Redirect(location); + } + else if (_authorizeEndpointRequest.IsImplicitGrantType) + { + string location = _clientContext.RedirectUri; + + DateTimeOffset currentUtc = Options.SystemClock.UtcNow; + signin.Properties.IssuedUtc = currentUtc; + signin.Properties.ExpiresUtc = currentUtc.Add(Options.AccessTokenExpireTimeSpan); + + // associate client_id with access token + signin.Properties.Items[Constants.Extra.ClientId] = _authorizeEndpointRequest.ClientId; + + var accessTokenContext = new AuthenticationTokenCreateContext(Context, Options.AccessTokenFormat, new AuthenticationTicket(signin.Principal, signin.Properties, signin.Identity.AuthenticationType)); + + await Options.AccessTokenProvider.CreateAsync(accessTokenContext); + + string accessToken = accessTokenContext.Token; + if (string.IsNullOrEmpty(accessToken)) + { + accessToken = accessTokenContext.SerializeTicket(); + } + + DateTimeOffset? accessTokenExpiresUtc = accessTokenContext.Ticket.Properties.ExpiresUtc; + + var appender = new Appender(location, '#'); + + appender.Append(Constants.Parameters.AccessToken, accessToken) + .Append(Constants.Parameters.TokenType, Constants.TokenTypes.Bearer); + + if (accessTokenExpiresUtc.HasValue) + { + TimeSpan? expiresTimeSpan = accessTokenExpiresUtc - currentUtc; + var expiresIn = (long)(expiresTimeSpan.Value.TotalSeconds + .5); + appender.Append(Constants.Parameters.ExpiresIn, expiresIn.ToString(CultureInfo.InvariantCulture)); + } + + if (!string.IsNullOrEmpty(_authorizeEndpointRequest.State)) + { + appender.Append(Constants.Parameters.State, _authorizeEndpointRequest.State); + } + + var authResponseContext = new OAuthAuthorizationEndpointResponseContext(Context, Options, new AuthenticationTicket(signin.Principal, signin.Properties, signin.Identity.AuthenticationType), _authorizeEndpointRequest, accessToken, null); + + await Options.Provider.AuthorizationEndpointResponse(authResponseContext); + + foreach (var parameter in authResponseContext.AdditionalResponseParameters) + { + appender.Append(parameter.Key, parameter.Value.ToString()); + } + + Response.Redirect(appender.ToString()); + } + } + + #endregion + } + +} diff --git a/Yavsc/Auth/AuthServer/OAuthAuthorizationServerMiddleware.cs b/Yavsc/Auth/AuthServer/OAuthAuthorizationServerMiddleware.cs new file mode 100644 index 00000000..e0d02bbc --- /dev/null +++ b/Yavsc/Auth/AuthServer/OAuthAuthorizationServerMiddleware.cs @@ -0,0 +1,100 @@ + +using Microsoft.AspNet.Authentication; +using Microsoft.AspNet.Builder; +using Microsoft.AspNet.DataProtection; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.WebEncoders; +using Microsoft.Extensions.DependencyInjection; +using System; + +namespace OAuth.AspNet.AuthServer +{ + + /// + /// Authorization Server middleware component which is added to an OWIN pipeline. This class is not + /// created by application code directly, instead it is added by calling the the IAppBuilder UseOAuthAuthorizationServer + /// extension method. + /// + public class OAuthAuthorizationServerMiddleware : AuthenticationMiddleware + { + /// + /// Authorization Server middleware component which is added to an OWIN pipeline. This constructor is not + /// called by application code directly, instead it is added by calling the the IAppBuilder UseOAuthAuthorizationServer + /// extension method. + /// + public OAuthAuthorizationServerMiddleware( + RequestDelegate next, + OAuthAuthorizationServerOptions options, + ILoggerFactory loggerFactory, + IDataProtectionProvider dataProtectionProvider, + IUrlEncoder encoder, + IApplicationStore applicationStore + ) : base(next, options, loggerFactory, encoder) + { + if (applicationStore == null ) + { + throw new InvalidOperationException("No application store"); + } + ApplicationStore = applicationStore; + + if (Options.Provider == null) + { + Options.Provider = new OAuthAuthorizationServerProvider(); + } + + if (Options.AuthorizationCodeFormat == null) + { + IDataProtector dataProtecter = dataProtectionProvider.CreateProtector(typeof(OAuthAuthorizationServerMiddleware).FullName, "Authentication_Code", "v1"); + + Options.AuthorizationCodeFormat = new TicketDataFormat(dataProtecter); + } + + if (Options.RefreshTokenFormat == null) + { + IDataProtector dataProtecter = dataProtectionProvider.CreateProtector(typeof(OAuthAuthorizationServerMiddleware).FullName, "Refresh_Token", "v1"); + + Options.RefreshTokenFormat = new TicketDataFormat(dataProtecter); + } + + if (Options.TokenDataProtector == null) + { + Options.TokenDataProtector = dataProtectionProvider.CreateProtector("OAuth.AspNet.AuthServer"); + + } + + if (Options.AccessTokenFormat == null) + { + IDataProtector dataProtecter = Options.TokenDataProtector.CreateProtector("Access_Token", "v1"); + + Options.AccessTokenFormat = new TicketDataFormat(dataProtecter); + } + + if (Options.AuthorizationCodeProvider == null) + { + Options.AuthorizationCodeProvider = new AuthenticationTokenProvider(); + } + + if (Options.AccessTokenProvider == null) + { + Options.AccessTokenProvider = new AuthenticationTokenProvider(); + } + + if (Options.RefreshTokenProvider == null) + { + Options.RefreshTokenProvider = new AuthenticationTokenProvider(); + } + + } + + private IApplicationStore ApplicationStore { get; set; } + /// + /// Called by the AuthenticationMiddleware base class to create a per-request handler. + /// + /// A new instance of the request handler + protected override AuthenticationHandler CreateHandler() + { + return new OAuthAuthorizationServerHandler(ApplicationStore); + } + } + +} \ No newline at end of file diff --git a/Yavsc/Auth/AuthServer/OAuthAuthorizationServerOptions.cs b/Yavsc/Auth/AuthServer/OAuthAuthorizationServerOptions.cs new file mode 100644 index 00000000..063bb080 --- /dev/null +++ b/Yavsc/Auth/AuthServer/OAuthAuthorizationServerOptions.cs @@ -0,0 +1,136 @@ +using Microsoft.AspNet.Authentication; +using Microsoft.AspNet.DataProtection; +using Microsoft.AspNet.Http; +using System; + +namespace OAuth.AspNet.AuthServer +{ + + /// + /// Options class provides information needed to control Authorization Server middleware behavior + /// + public class OAuthAuthorizationServerOptions : AuthenticationOptions + { + /// + /// Creates an instance of authorization server options with default values. + /// + public OAuthAuthorizationServerOptions() + { + AuthenticationScheme = OAuthDefaults.AuthenticationType; + AuthorizationCodeExpireTimeSpan = TimeSpan.FromMinutes(5); + AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(20); + SystemClock = new SystemClock(); + } + + /// + /// The request path where client applications will redirect the user-agent in order to + /// obtain user consent to issue a token. Must begin with a leading slash, like "/Authorize". + /// + public PathString AuthorizeEndpointPath { get; set; } + + /// + /// The request path client applications communicate with directly as part of the OAuth protocol. + /// Must begin with a leading slash, like "/Token". If the client is issued a client_secret, it must + /// be provided to this endpoint. + /// + public PathString TokenEndpointPath { get; set; } + + /// + /// The object provided by the application to process events raised by the Authorization Server middleware. + /// The application may implement the interface fully, or it may create an instance of OAuthAuthorizationServerProvider + /// and assign delegates only to the events it wants to process. + /// + public IOAuthAuthorizationServerProvider Provider { get; set; } + + /// + /// The data format used to protect and unprotect the information contained in the authorization code. + /// If not provided by the application the default data protection provider depends on the host server. + /// The SystemWeb host on IIS will use ASP.NET machine key data protection, and HttpListener and other self-hosted + /// servers will use DPAPI data protection. + /// + public ISecureDataFormat AuthorizationCodeFormat { get; set; } + + /// + /// The data protection provider used to protect token information. + /// + public IDataProtector TokenDataProtector { get; set; } + + /// + /// The data format used to protect the information contained in the access token. + /// If not provided by the application the default data protection provider depends on the host server. + /// The SystemWeb host on IIS will use ASP.NET machine key data protection, and HttpListener and other self-hosted + /// servers will use DPAPI data protection. If a different access token + /// provider or format is assigned, a compatible instance must be assigned to the OAuthBearerAuthenticationOptions.AccessTokenProvider + /// or OAuthBearerAuthenticationOptions.AccessTokenFormat property of the resource server. + /// + public ISecureDataFormat AccessTokenFormat { get; set; } + + /// + /// The data format used to protect and unprotect the information contained in the refresh token. + /// If not provided by the application the default data protection provider depends on the host server. + /// The SystemWeb host on IIS will use ASP.NET machine key data protection, and HttpListener and other self-hosted + /// servers will use DPAPI data protection. + /// + public ISecureDataFormat RefreshTokenFormat { get; set; } + + /// + /// The period of time the authorization code remains valid after being issued. The default is five minutes. + /// This time span must also take into account clock synchronization between servers in a web farm, so a very + /// brief value could result in unexpectedly expired tokens. + /// + public TimeSpan AuthorizationCodeExpireTimeSpan { get; set; } + + /// + /// The period of time the access token remains valid after being issued. The default is twenty minutes. + /// The client application is expected to refresh or acquire a new access token after the token has expired. + /// + public TimeSpan AccessTokenExpireTimeSpan { get; set; } + + /// + /// Produces a single-use authorization code to return to the client application. For the OAuth server to be secure the + /// application MUST provide an instance for AuthorizationCodeProvider where the token produced by the OnCreate or OnCreateAsync event + /// is considered valid for only one call to OnReceive or OnReceiveAsync. + /// + public IAuthenticationTokenProvider AuthorizationCodeProvider { get; set; } + + /// + /// Produces a bearer token the client application will typically be providing to resource server as the authorization bearer + /// http request header. If not provided the token produced on the server's default data protection. If a different access token + /// provider or format is assigned, a compatible instance must be assigned to the OAuthBearerAuthenticationOptions.AccessTokenProvider + /// or OAuthBearerAuthenticationOptions.AccessTokenFormat property of the resource server. + /// + public IAuthenticationTokenProvider AccessTokenProvider { get; set; } + + /// + /// Produces a refresh token which may be used to produce a new access token when needed. If not provided the authorization server will + /// not return refresh tokens from the /Token endpoint. + /// + public IAuthenticationTokenProvider RefreshTokenProvider { get; set; } + + /// + /// Set to true if the web application is able to render error messages on the /Authorize endpoint. This is only needed for cases where + /// the browser is not redirected back to the client application, for example, when the client_id or redirect_uri are incorrect. The + /// /Authorize endpoint should expect to see "oauth.Error", "oauth.ErrorDescription", "oauth.ErrorUri" properties added to the owin environment. + /// + public bool ApplicationCanDisplayErrors { get; set; } + + /// + /// Used to know what the current clock time is when calculating or validating token expiration. When not assigned default is based on + /// DateTimeOffset.UtcNow. This is typically needed only for unit testing. + /// + public ISystemClock SystemClock { get; set; } + + /// + /// True to allow authorize and token requests to arrive on http URI addresses, and to allow incoming + /// redirect_uri authorize request parameter to have http URI addresses. + /// + public bool AllowInsecureHttp { get; set; } + + /// + /// Endpoint responsible for Form Post Response Mode + /// See also, http://openid.net/specs/oauth-v2-form-post-response-mode-1_0.html + /// + public PathString FormPostEndpoint { get; set; } + } + +} diff --git a/Yavsc/Auth/AuthServer/OAuthAuthorizationServerProvider.cs b/Yavsc/Auth/AuthServer/OAuthAuthorizationServerProvider.cs new file mode 100644 index 00000000..ced87431 --- /dev/null +++ b/Yavsc/Auth/AuthServer/OAuthAuthorizationServerProvider.cs @@ -0,0 +1,378 @@ +using System; +using System.Threading.Tasks; + +namespace OAuth.AspNet.AuthServer +{ + + /// + /// Default implementation of IOAuthAuthorizationServerProvider used by Authorization + /// Server to communicate with the web application while processing requests. OAuthAuthorizationServerProvider provides some default behavior, + /// may be used as a virtual base class, and offers delegate properties which may be used to + /// handle individual calls without declaring a new class type. + /// + public class OAuthAuthorizationServerProvider : IOAuthAuthorizationServerProvider + { + /// + /// Creates new instance of default provider behavior + /// + public OAuthAuthorizationServerProvider() + { + OnMatchEndpoint = context => Task.FromResult(null); + OnValidateClientRedirectUri = context => Task.FromResult(null); + OnValidateClientAuthentication = context => Task.FromResult(null); + + OnValidateAuthorizeRequest = DefaultBehavior.ValidateAuthorizeRequest; + OnValidateTokenRequest = DefaultBehavior.ValidateTokenRequest; + + OnGrantAuthorizationCode = DefaultBehavior.GrantAuthorizationCode; + OnGrantResourceOwnerCredentials = context => Task.FromResult(null); + OnGrantRefreshToken = DefaultBehavior.GrantRefreshToken; + OnGrantClientCredentials = context => Task.FromResult(null); + OnGrantCustomExtension = context => Task.FromResult(null); + + OnAuthorizeEndpoint = context => Task.FromResult(null); + OnTokenEndpoint = context => Task.FromResult(null); + + OnAuthorizationEndpointResponse = context => Task.FromResult(null); + + OnTokenEndpointResponse = context => Task.FromResult(null); + } + + /// + /// Called to determine if an incoming request is treated as an Authorize or Token + /// endpoint. If Options.AuthorizeEndpointPath or Options.TokenEndpointPath + /// are assigned values, then handling this event is optional and context.IsAuthorizeEndpoint and context.IsTokenEndpoint + /// will already be true if the request path matches. + /// + public Func OnMatchEndpoint { get; set; } + + /// + /// Called to validate that the context.ClientId is a registered "client_id", and that the context.RedirectUri a "redirect_uri" + /// registered for that client. This only occurs when processing the Authorize endpoint. The application MUST implement this + /// call, and it MUST validate both of those factors before calling context.Validated. If the context.Validated method is called + /// with a given redirectUri parameter, then IsValidated will only become true if the incoming redirect URI matches the given redirect URI. + /// If context.Validated is not called the request will not proceed further. + /// + public Func OnValidateClientRedirectUri { get; set; } + + /// + /// Called to validate that the origin of the request is a registered "client_id", and that the correct credentials for that client are + /// present on the request. If the web application accepts Basic authentication credentials, + /// context.TryGetBasicCredentials(out clientId, out clientSecret) may be called to acquire those values if present in the request header. If the web + /// application accepts "client_id" and "client_secret" as form encoded POST parameters, + /// context.TryGetFormCredentials(out clientId, out clientSecret) may be called to acquire those values if present in the request body. + /// If context.Validated is not called the request will not proceed further. + /// + public Func OnValidateClientAuthentication { get; set; } + + /// + /// Called for each request to the Authorize endpoint to determine if the request is valid and should continue. + /// The default behavior when using the OAuthAuthorizationServerProvider is to assume well-formed requests, with + /// validated client redirect URI, should continue processing. An application may add any additional constraints. + /// + public Func OnValidateAuthorizeRequest { get; set; } + + /// + /// Called for each request to the Token endpoint to determine if the request is valid and should continue. + /// The default behavior when using the OAuthAuthorizationServerProvider is to assume well-formed requests, with + /// validated client credentials, should continue processing. An application may add any additional constraints. + /// + public Func OnValidateTokenRequest { get; set; } + + /// + /// Called when a request to the Token endpoint arrives with a "grant_type" of "authorization_code". This occurs after the Authorize + /// endpoint as redirected the user-agent back to the client with a "code" parameter, and the client is exchanging that for an "access_token". + /// The claims and properties + /// associated with the authorization code are present in the context.Ticket. The application must call context.Validated to instruct the Authorization + /// Server middleware to issue an access token based on those claims and properties. The call to context.Validated may be given a different + /// AuthenticationTicket or ClaimsIdentity in order to control which information flows from authorization code to access token. + /// The default behavior when using the OAuthAuthorizationServerProvider is to flow information from the authorization code to + /// the access token unmodified. + /// See also http://tools.ietf.org/html/rfc6749#section-4.1.3 + /// + public Func OnGrantAuthorizationCode { get; set; } + + /// + /// Called when a request to the Token endpoint arrives with a "grant_type" of "password". This occurs when the user has provided name and password + /// credentials directly into the client application's user interface, and the client application is using those to acquire an "access_token" and + /// optional "refresh_token". If the web application supports the + /// resource owner credentials grant type it must validate the context.Username and context.Password as appropriate. To issue an + /// access token the context.Validated must be called with a new ticket containing the claims about the resource owner which should be associated + /// with the access token. The application should take appropriate measures to ensure that the endpoint isn’t abused by malicious callers. + /// The default behavior is to reject this grant type. + /// See also http://tools.ietf.org/html/rfc6749#section-4.3.2 + /// + public Func OnGrantResourceOwnerCredentials { get; set; } + + /// + /// Called when a request to the Token endpoint arrives with a "grant_type" of "client_credentials". This occurs when a registered client + /// application wishes to acquire an "access_token" to interact with protected resources on it's own behalf, rather than on behalf of an authenticated user. + /// If the web application supports the client credentials it may assume the context.ClientId has been validated by the ValidateClientAuthentication call. + /// To issue an access token the context.Validated must be called with a new ticket containing the claims about the client application which should be associated + /// with the access token. The application should take appropriate measures to ensure that the endpoint isn’t abused by malicious callers. + /// The default behavior is to reject this grant type. + /// See also http://tools.ietf.org/html/rfc6749#section-4.4.2 + /// + public Func OnGrantClientCredentials { get; set; } + + /// + /// Called when a request to the Token endpoint arrives with a "grant_type" of "refresh_token". This occurs if your application has issued a "refresh_token" + /// along with the "access_token", and the client is attempting to use the "refresh_token" to acquire a new "access_token", and possibly a new "refresh_token". + /// To issue a refresh token the an Options.RefreshTokenProvider must be assigned to create the value which is returned. The claims and properties + /// associated with the refresh token are present in the context.Ticket. The application must call context.Validated to instruct the + /// Authorization Server middleware to issue an access token based on those claims and properties. The call to context.Validated may + /// be given a different AuthenticationTicket or ClaimsIdentity in order to control which information flows from the refresh token to + /// the access token. The default behavior when using the OAuthAuthorizationServerProvider is to flow information from the refresh token to + /// the access token unmodified. + /// See also http://tools.ietf.org/html/rfc6749#section-6 + /// + public Func OnGrantRefreshToken { get; set; } + + /// + /// Called when a request to the Token andpoint arrives with a "grant_type" of any other value. If the application supports custom grant types + /// it is entirely responsible for determining if the request should result in an access_token. If context.Validated is called with ticket + /// information the response body is produced in the same way as the other standard grant types. If additional response parameters must be + /// included they may be added in the final TokenEndpoint call. + /// See also http://tools.ietf.org/html/rfc6749#section-4.5 + /// + public Func OnGrantCustomExtension { get; set; } + + /// + /// Called at the final stage of an incoming Authorize endpoint request before the execution continues on to the web application component + /// responsible for producing the html response. Anything present in the OWIN pipeline following the Authorization Server may produce the + /// response for the Authorize page. If running on IIS any ASP.NET technology running on the server may produce the response for the + /// Authorize page. If the web application wishes to produce the response directly in the AuthorizeEndpoint call it may write to the + /// context.Response directly and should call context.RequestCompleted to stop other handlers from executing. If the web application wishes + /// to grant the authorization directly in the AuthorizeEndpoint call it cay call context.OwinContext.Authentication.SignIn with the + /// appropriate ClaimsIdentity and should call context.RequestCompleted to stop other handlers from executing. + /// + public Func OnAuthorizeEndpoint { get; set; } + + /// + /// Called at the final stage of a successful Token endpoint request. An application may implement this call in order to do any final + /// modification of the claims being used to issue access or refresh tokens. This call may also be used in order to add additional + /// response parameters to the Token endpoint's json response body. + /// + public Func OnTokenEndpoint { get; set; } + + /// + /// Called before the AuthorizationEndpoint redirects its response to the caller. The response could be the + /// token, when using implicit flow or the AuthorizationEndpoint when using authorization code flow. + /// An application may implement this call in order to do any final modification of the claims being used + /// to issue access or refresh tokens. This call may also be used in order to add additional + /// response parameters to the authorization endpoint's response. + /// + /// The context of the event carries information in and results out. + /// Task to enable asynchronous execution + public Func OnAuthorizationEndpointResponse { get; set; } + + /// + /// Called before the TokenEndpoint redirects its response to the caller. + /// + /// + /// + public Func OnTokenEndpointResponse { get; set; } + + /// + /// Called to determine if an incoming request is treated as an Authorize or Token + /// endpoint. If Options.AuthorizeEndpointPath or Options.TokenEndpointPath + /// are assigned values, then handling this event is optional and context.IsAuthorizeEndpoint and context.IsTokenEndpoint + /// will already be true if the request path matches. + /// + /// The context of the event carries information in and results out. + /// Task to enable asynchronous execution + public virtual Task MatchEndpoint(OAuthMatchContext context) + { + return OnMatchEndpoint.Invoke(context); + } + + /// + /// Called to validate that the context.ClientId is a registered "client_id", and that the context.RedirectUri a "redirect_uri" + /// registered for that client. This only occurs when processing the Authorize endpoint. The application MUST implement this + /// call, and it MUST validate both of those factors before calling context.Validated. If the context.Validated method is called + /// with a given redirectUri parameter, then IsValidated will only become true if the incoming redirect URI matches the given redirect URI. + /// If context.Validated is not called the request will not proceed further. + /// + /// The context of the event carries information in and results out. + /// Task to enable asynchronous execution + public virtual Task ValidateClientRedirectUri(OAuthValidateClientRedirectUriContext context) + { + return OnValidateClientRedirectUri.Invoke(context); + } + + /// + /// Called to validate that the origin of the request is a registered "client_id", and that the correct credentials for that client are + /// present on the request. If the web application accepts Basic authentication credentials, + /// context.TryGetBasicCredentials(out clientId, out clientSecret) may be called to acquire those values if present in the request header. If the web + /// application accepts "client_id" and "client_secret" as form encoded POST parameters, + /// context.TryGetFormCredentials(out clientId, out clientSecret) may be called to acquire those values if present in the request body. + /// If context.Validated is not called the request will not proceed further. + /// + /// The context of the event carries information in and results out. + /// Task to enable asynchronous execution + public virtual Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context) + { + return OnValidateClientAuthentication.Invoke(context); + } + + /// + /// Called for each request to the Authorize endpoint to determine if the request is valid and should continue. + /// The default behavior when using the OAuthAuthorizationServerProvider is to assume well-formed requests, with + /// validated client redirect URI, should continue processing. An application may add any additional constraints. + /// + /// The context of the event carries information in and results out. + /// Task to enable asynchronous execution + public virtual Task ValidateAuthorizeRequest(OAuthValidateAuthorizeRequestContext context) + { + return OnValidateAuthorizeRequest.Invoke(context); + } + + /// + /// Called for each request to the Token endpoint to determine if the request is valid and should continue. + /// The default behavior when using the OAuthAuthorizationServerProvider is to assume well-formed requests, with + /// validated client credentials, should continue processing. An application may add any additional constraints. + /// + /// The context of the event carries information in and results out. + /// Task to enable asynchronous execution + public virtual Task ValidateTokenRequest(OAuthValidateTokenRequestContext context) + { + return OnValidateTokenRequest.Invoke(context); + } + + /// + /// Called when a request to the Token endpoint arrives with a "grant_type" of "authorization_code". This occurs after the Authorize + /// endpoint as redirected the user-agent back to the client with a "code" parameter, and the client is exchanging that for an "access_token". + /// The claims and properties + /// associated with the authorization code are present in the context.Ticket. The application must call context.Validated to instruct the Authorization + /// Server middleware to issue an access token based on those claims and properties. The call to context.Validated may be given a different + /// AuthenticationTicket or ClaimsIdentity in order to control which information flows from authorization code to access token. + /// The default behavior when using the OAuthAuthorizationServerProvider is to flow information from the authorization code to + /// the access token unmodified. + /// See also http://tools.ietf.org/html/rfc6749#section-4.1.3 + /// + /// The context of the event carries information in and results out. + /// Task to enable asynchronous execution + public virtual Task GrantAuthorizationCode(OAuthGrantAuthorizationCodeContext context) + { + return OnGrantAuthorizationCode.Invoke(context); + } + + /// + /// Called when a request to the Token endpoint arrives with a "grant_type" of "refresh_token". This occurs if your application has issued a "refresh_token" + /// along with the "access_token", and the client is attempting to use the "refresh_token" to acquire a new "access_token", and possibly a new "refresh_token". + /// To issue a refresh token the an Options.RefreshTokenProvider must be assigned to create the value which is returned. The claims and properties + /// associated with the refresh token are present in the context.Ticket. The application must call context.Validated to instruct the + /// Authorization Server middleware to issue an access token based on those claims and properties. The call to context.Validated may + /// be given a different AuthenticationTicket or ClaimsIdentity in order to control which information flows from the refresh token to + /// the access token. The default behavior when using the OAuthAuthorizationServerProvider is to flow information from the refresh token to + /// the access token unmodified. + /// See also http://tools.ietf.org/html/rfc6749#section-6 + /// + /// The context of the event carries information in and results out. + /// Task to enable asynchronous execution + public virtual Task GrantRefreshToken(OAuthGrantRefreshTokenContext context) + { + return OnGrantRefreshToken.Invoke(context); + } + + /// + /// Called when a request to the Token endpoint arrives with a "grant_type" of "password". This occurs when the user has provided name and password + /// credentials directly into the client application's user interface, and the client application is using those to acquire an "access_token" and + /// optional "refresh_token". If the web application supports the + /// resource owner credentials grant type it must validate the context.Username and context.Password as appropriate. To issue an + /// access token the context.Validated must be called with a new ticket containing the claims about the resource owner which should be associated + /// with the access token. The application should take appropriate measures to ensure that the endpoint isn’t abused by malicious callers. + /// The default behavior is to reject this grant type. + /// See also http://tools.ietf.org/html/rfc6749#section-4.3.2 + /// + /// The context of the event carries information in and results out. + /// Task to enable asynchronous execution + public virtual Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context) + { + return OnGrantResourceOwnerCredentials.Invoke(context); + } + + /// + /// Called when a request to the Token endpoint arrives with a "grant_type" of "client_credentials". This occurs when a registered client + /// application wishes to acquire an "access_token" to interact with protected resources on it's own behalf, rather than on behalf of an authenticated user. + /// If the web application supports the client credentials it may assume the context.ClientId has been validated by the ValidateClientAuthentication call. + /// To issue an access token the context.Validated must be called with a new ticket containing the claims about the client application which should be associated + /// with the access token. The application should take appropriate measures to ensure that the endpoint isn’t abused by malicious callers. + /// The default behavior is to reject this grant type. + /// See also http://tools.ietf.org/html/rfc6749#section-4.4.2 + /// + /// The context of the event carries information in and results out. + /// Task to enable asynchronous execution + public virtual Task GrantClientCredentials(OAuthGrantClientCredentialsContext context) + { + return OnGrantClientCredentials.Invoke(context); + } + + /// + /// Called when a request to the Token endpoint arrives with a "grant_type" of any other value. If the application supports custom grant types + /// it is entirely responsible for determining if the request should result in an access_token. If context.Validated is called with ticket + /// information the response body is produced in the same way as the other standard grant types. If additional response parameters must be + /// included they may be added in the final TokenEndpoint call. + /// See also http://tools.ietf.org/html/rfc6749#section-4.5 + /// + /// The context of the event carries information in and results out. + /// Task to enable asynchronous execution + public virtual Task GrantCustomExtension(OAuthGrantCustomExtensionContext context) + { + return OnGrantCustomExtension.Invoke(context); + } + + /// + /// Called at the final stage of an incoming Authorize endpoint request before the execution continues on to the web application component + /// responsible for producing the html response. Anything present in the OWIN pipeline following the Authorization Server may produce the + /// response for the Authorize page. If running on IIS any ASP.NET technology running on the server may produce the response for the + /// Authorize page. If the web application wishes to produce the response directly in the AuthorizeEndpoint call it may write to the + /// context.Response directly and should call context.RequestCompleted to stop other handlers from executing. If the web application wishes + /// to grant the authorization directly in the AuthorizeEndpoint call it cay call context.OwinContext.Authentication.SignIn with the + /// appropriate ClaimsIdentity and should call context.RequestCompleted to stop other handlers from executing. + /// + /// The context of the event carries information in and results out. + /// Task to enable asynchronous execution + public virtual Task AuthorizeEndpoint(OAuthAuthorizeEndpointContext context) + { + return OnAuthorizeEndpoint.Invoke(context); + } + + /// + /// Called at the final stage of a successful Token endpoint request. An application may implement this call in order to do any final + /// modification of the claims being used to issue access or refresh tokens. This call may also be used in order to add additional + /// response parameters to the Token endpoint's json response body. + /// + /// The context of the event carries information in and results out. + /// Task to enable asynchronous execution + public virtual Task TokenEndpoint(OAuthTokenEndpointContext context) + { + return OnTokenEndpoint.Invoke(context); + } + + /// + /// Called before the AuthorizationEndpoint redirects its response to the caller. The response could be the + /// token, when using implicit flow or the AuthorizationEndpoint when using authorization code flow. + /// An application may implement this call in order to do any final modification of the claims being used + /// to issue access or refresh tokens. This call may also be used in order to add additional + /// response parameters to the authorization endpoint's response. + /// + /// The context of the event carries information in and results out. + /// Task to enable asynchronous execution + public virtual Task AuthorizationEndpointResponse(OAuthAuthorizationEndpointResponseContext context) + { + return OnAuthorizationEndpointResponse.Invoke(context); + } + + /// + /// Called before the TokenEndpoint redirects its response to the caller. + /// + /// + /// + public virtual Task TokenEndpointResponse(OAuthTokenEndpointResponseContext context) + { + return OnTokenEndpointResponse.Invoke(context); + } + } + +} diff --git a/Yavsc/Auth/AuthServer/OAuthAuthorizeEndpointContext.cs b/Yavsc/Auth/AuthServer/OAuthAuthorizeEndpointContext.cs new file mode 100644 index 00000000..e530c747 --- /dev/null +++ b/Yavsc/Auth/AuthServer/OAuthAuthorizeEndpointContext.cs @@ -0,0 +1,34 @@ +using Microsoft.AspNet.Authentication; +using Microsoft.AspNet.Http; + +namespace OAuth.AspNet.AuthServer +{ + + /// + /// An event raised after the Authorization Server has processed the request, but before it is passed on to the web application. + /// Calling RequestCompleted will prevent the request from passing on to the web application. + /// + public class OAuthAuthorizeEndpointContext : BaseOAuthEndpointContext + { + /// + /// Creates an instance of this context + /// + public OAuthAuthorizeEndpointContext(HttpContext context, OAuthAuthorizationServerOptions options, AuthorizeEndpointRequest authorizeRequest) : base(context, options) + { + AuthorizeRequest = authorizeRequest; + } + + /// + /// Gets OAuth authorization request data. + /// + public AuthorizeEndpointRequest AuthorizeRequest { get; private set; } + + public bool IsRequestCompleted { get; private set; } + + public void RequestCompleted() + { + IsRequestCompleted = true; + } + } + +} diff --git a/Yavsc/Auth/AuthServer/OAuthAuthorizeEndpointResponseContext.cs b/Yavsc/Auth/AuthServer/OAuthAuthorizeEndpointResponseContext.cs new file mode 100644 index 00000000..6f71c764 --- /dev/null +++ b/Yavsc/Auth/AuthServer/OAuthAuthorizeEndpointResponseContext.cs @@ -0,0 +1,69 @@ +using Microsoft.AspNet.Authentication; +using Microsoft.AspNet.Http; +using Microsoft.AspNet.Http.Authentication; +using System; +using System.Collections.Generic; +using System.Security.Claims; + +namespace OAuth.AspNet.AuthServer +{ + + /// + /// Provides context information when processing an Authorization Response + /// + public class OAuthAuthorizationEndpointResponseContext : BaseOAuthEndpointContext + { + /// + /// Initializes a new instance of the class + /// + /// + /// + /// + /// + public OAuthAuthorizationEndpointResponseContext(HttpContext context, OAuthAuthorizationServerOptions options, AuthenticationTicket ticket, AuthorizeEndpointRequest authorizeEndpointRequest, string accessToken, string authorizationCode) : base(context, options) + { + if (ticket == null) + { + throw new ArgumentNullException("ticket"); + } + + Principal = ticket.Principal; + Properties = ticket.Properties; + AuthorizeEndpointRequest = authorizeEndpointRequest; + AdditionalResponseParameters = new Dictionary(StringComparer.Ordinal); + AccessToken = accessToken; + AuthorizationCode = authorizationCode; + } + + /// + /// Gets the identity of the resource owner. + /// + public ClaimsPrincipal Principal { get; private set; } + + /// + /// Dictionary containing the state of the authentication session. + /// + public AuthenticationProperties Properties { get; private set; } + + /// + /// Gets information about the authorize endpoint request. + /// + public AuthorizeEndpointRequest AuthorizeEndpointRequest { get; private set; } + + /// + /// Enables additional values to be appended to the token response. + /// + public IDictionary AdditionalResponseParameters { get; private set; } + + /// + /// The serialized Access-Token. Depending on the flow, it can be null. + /// + public string AccessToken { get; private set; } + + /// + /// The created Authorization-Code. Depending on the flow, it can be null. + /// + public string AuthorizationCode { get; private set; } + } + +} diff --git a/Yavsc/Auth/AuthServer/OAuthConstants.cs b/Yavsc/Auth/AuthServer/OAuthConstants.cs new file mode 100644 index 00000000..a7d2923e --- /dev/null +++ b/Yavsc/Auth/AuthServer/OAuthConstants.cs @@ -0,0 +1,70 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace OAuth.AspNet.AuthServer +{ + internal static class Constants + { + public static class Parameters + { + public const string ResponseType = "response_type"; + public const string GrantType = "grant_type"; + public const string ClientId = "client_id"; + public const string ClientSecret = "client_secret"; + public const string RedirectUri = "redirect_uri"; + public const string Scope = "scope"; + public const string State = "state"; + public const string Code = "code"; + public const string RefreshToken = "refresh_token"; + public const string Username = "username"; + public const string Password = "password"; + public const string Error = "error"; + public const string ErrorDescription = "error_description"; + public const string ErrorUri = "error_uri"; + public const string ExpiresIn = "expires_in"; + public const string AccessToken = "access_token"; + public const string TokenType = "token_type"; + + public const string ResponseMode = "response_mode"; + } + + public static class ResponseTypes + { + public const string Code = "code"; + public const string Token = "token"; + } + + public static class GrantTypes + { + public const string AuthorizationCode = "authorization_code"; + public const string ClientCredentials = "client_credentials"; + public const string RefreshToken = "refresh_token"; + public const string Password = "password"; + } + + public static class TokenTypes + { + public const string Bearer = "bearer"; + } + + public static class Errors + { + public const string InvalidRequest = "invalid_request"; + public const string InvalidClient = "invalid_client"; + public const string InvalidGrant = "invalid_grant"; + public const string UnsupportedResponseType = "unsupported_response_type"; + public const string UnsupportedGrantType = "unsupported_grant_type"; + public const string UnauthorizedClient = "unauthorized_client"; + } + + public static class Extra + { + public const string ClientId = "client_id"; + public const string RedirectUri = "redirect_uri"; + } + + public static class ResponseModes + { + public const string FormPost = "form_post"; + } + } +} diff --git a/Yavsc/Auth/AuthServer/OAuthDefaults.cs b/Yavsc/Auth/AuthServer/OAuthDefaults.cs new file mode 100644 index 00000000..1f6768da --- /dev/null +++ b/Yavsc/Auth/AuthServer/OAuthDefaults.cs @@ -0,0 +1,15 @@ + +namespace OAuth.AspNet.AuthServer +{ + /// + /// Default values used by authorization server and bearer authentication. + /// + public static class OAuthDefaults + { + /// + /// Default value for AuthenticationType property in the OAuthBearerAuthenticationOptions and + /// OAuthAuthorizationServerOptions. + /// + public const string AuthenticationType = "Bearer"; + } +} diff --git a/Yavsc/Auth/AuthServer/OAuthGrantAuthorizationCodeContext.cs b/Yavsc/Auth/AuthServer/OAuthGrantAuthorizationCodeContext.cs new file mode 100644 index 00000000..9ca37907 --- /dev/null +++ b/Yavsc/Auth/AuthServer/OAuthGrantAuthorizationCodeContext.cs @@ -0,0 +1,21 @@ +using Microsoft.AspNet.Authentication; +using Microsoft.AspNet.Http; + +namespace OAuth.AspNet.AuthServer +{ + + /// + /// Provides context information when handling an OAuth authorization code grant. + /// + public class OAuthGrantAuthorizationCodeContext : BaseValidatingTicketContext + { + /// + /// Initializes a new instance of the class + /// + /// + /// + /// + public OAuthGrantAuthorizationCodeContext(HttpContext context, OAuthAuthorizationServerOptions options, AuthenticationTicket ticket) : base(context, options, ticket) { } + } + +} diff --git a/Yavsc/Auth/AuthServer/OAuthGrantClientCredentialsContext.cs b/Yavsc/Auth/AuthServer/OAuthGrantClientCredentialsContext.cs new file mode 100644 index 00000000..159e9d5e --- /dev/null +++ b/Yavsc/Auth/AuthServer/OAuthGrantClientCredentialsContext.cs @@ -0,0 +1,36 @@ +using Microsoft.AspNet.Http; +using System.Collections.Generic; + +namespace OAuth.AspNet.AuthServer +{ + + /// + /// Provides context information used in handling an OAuth client credentials grant. + /// + public class OAuthGrantClientCredentialsContext : BaseValidatingTicketContext + { + /// + /// Initializes a new instance of the class + /// + /// + /// + /// + /// + public OAuthGrantClientCredentialsContext(HttpContext context, OAuthAuthorizationServerOptions options, string clientId, IList scope) : base(context, options, null) + { + ClientId = clientId; + Scope = scope; + } + + /// + /// OAuth client id. + /// + public string ClientId { get; private set; } + + /// + /// List of scopes allowed by the resource owner. + /// + public IList Scope { get; private set; } + } + +} diff --git a/Yavsc/Auth/AuthServer/OAuthGrantCustomExtensionContext.cs b/Yavsc/Auth/AuthServer/OAuthGrantCustomExtensionContext.cs new file mode 100644 index 00000000..bcfc2f3e --- /dev/null +++ b/Yavsc/Auth/AuthServer/OAuthGrantCustomExtensionContext.cs @@ -0,0 +1,42 @@ +using Microsoft.AspNet.Http; + +namespace OAuth.AspNet.AuthServer +{ + + /// + /// Provides context information used when handling OAuth extension grant types. + /// + public class OAuthGrantCustomExtensionContext : BaseValidatingTicketContext + { + /// + /// Initializes a new instance of the class + /// + /// + /// + /// + /// + /// + public OAuthGrantCustomExtensionContext(HttpContext context, OAuthAuthorizationServerOptions options, string clientId, string grantType, IReadableStringCollection parameters) : base(context, options, null) + { + ClientId = clientId; + GrantType = grantType; + Parameters = parameters; + } + + /// + /// Gets the OAuth client id. + /// + public string ClientId { get; private set; } + + /// + /// Gets the name of the OAuth extension grant type. + /// + public string GrantType { get; private set; } + + /// + /// Gets a list of additional parameters from the token request. + /// + public IReadableStringCollection Parameters { get; private set; } + } + +} diff --git a/Yavsc/Auth/AuthServer/OAuthGrantRefreshTokenContext.cs b/Yavsc/Auth/AuthServer/OAuthGrantRefreshTokenContext.cs new file mode 100644 index 00000000..5a477749 --- /dev/null +++ b/Yavsc/Auth/AuthServer/OAuthGrantRefreshTokenContext.cs @@ -0,0 +1,30 @@ +using Microsoft.AspNet.Authentication; +using Microsoft.AspNet.Http; + +namespace OAuth.AspNet.AuthServer +{ + + /// + /// Provides context information used when granting an OAuth refresh token. + /// + public class OAuthGrantRefreshTokenContext : BaseValidatingTicketContext + { + /// + /// Initializes a new instance of the class + /// + /// + /// + /// + /// + public OAuthGrantRefreshTokenContext(HttpContext context, OAuthAuthorizationServerOptions options, AuthenticationTicket ticket, string clientId) : base(context, options, ticket) + { + ClientId = clientId; + } + + /// + /// The OAuth client id. + /// + public string ClientId { get; private set; } + } + +} diff --git a/Yavsc/Auth/AuthServer/OAuthGrantResourceOwnerCredentialsContext.cs b/Yavsc/Auth/AuthServer/OAuthGrantResourceOwnerCredentialsContext.cs new file mode 100644 index 00000000..79ed8387 --- /dev/null +++ b/Yavsc/Auth/AuthServer/OAuthGrantResourceOwnerCredentialsContext.cs @@ -0,0 +1,50 @@ +using Microsoft.AspNet.Http; +using System.Collections.Generic; + +namespace OAuth.AspNet.AuthServer +{ + + /// + /// Provides context information used in handling an OAuth resource owner grant. + /// + public class OAuthGrantResourceOwnerCredentialsContext : BaseValidatingTicketContext + { + /// + /// Initializes a new instance of the class + /// + /// + /// + /// + /// + /// + /// + public OAuthGrantResourceOwnerCredentialsContext(HttpContext context, OAuthAuthorizationServerOptions options, string clientId, string userName, string password, IList scope) : base(context, options, null) + { + ClientId = clientId; + UserName = userName; + Password = password; + Scope = scope; + } + + /// + /// OAuth client id. + /// + public string ClientId { get; private set; } + + /// + /// Resource owner username. + /// + public string UserName { get; private set; } + + /// + /// Resource owner password. + /// + public string Password { get; private set; } + + /// + /// List of scopes allowed by the resource owner. + /// + public IList Scope { get; private set; } + } + +} diff --git a/Yavsc/Auth/AuthServer/OAuthMatchContext.cs b/Yavsc/Auth/AuthServer/OAuthMatchContext.cs new file mode 100644 index 00000000..e2a482de --- /dev/null +++ b/Yavsc/Auth/AuthServer/OAuthMatchContext.cs @@ -0,0 +1,74 @@ +using Microsoft.AspNet.Authentication; +using Microsoft.AspNet.Http; +using System; + +namespace OAuth.AspNet.AuthServer +{ + + /// + /// Provides notification used for determining the OAuth flow type based on the request. + /// + public class OAuthMatchContext : BaseControlContext + { + #region Constructors + + /// + /// Initializes a new instance of the class + /// + /// + /// + public OAuthMatchContext(HttpContext context, OAuthAuthorizationServerOptions options) : base(context) + { + if (options == null) + throw new ArgumentNullException(nameof(options)); + + Options = options; + } + + #endregion + + #region Public Members + + public OAuthAuthorizationServerOptions Options { get; } + + /// + /// Gets whether or not the endpoint is an OAuth authorize endpoint. + /// + public bool IsAuthorizeEndpoint { get; private set; } + + /// + /// Gets whether or not the endpoint is an OAuth token endpoint. + /// + public bool IsTokenEndpoint { get; private set; } + + /// + /// Sets the endpoint type to authorize endpoint. + /// + public void MatchesAuthorizeEndpoint() + { + IsAuthorizeEndpoint = true; + IsTokenEndpoint = false; + } + + /// + /// Sets the endpoint type to token endpoint. + /// + public void MatchesTokenEndpoint() + { + IsAuthorizeEndpoint = false; + IsTokenEndpoint = true; + } + + /// + /// Sets the endpoint type to neither authorize nor token. + /// + public void MatchesNothing() + { + IsAuthorizeEndpoint = false; + IsTokenEndpoint = false; + } + + #endregion + } + +} diff --git a/Yavsc/Auth/AuthServer/OAuthTokenEndpointContext.cs b/Yavsc/Auth/AuthServer/OAuthTokenEndpointContext.cs new file mode 100644 index 00000000..34dffd06 --- /dev/null +++ b/Yavsc/Auth/AuthServer/OAuthTokenEndpointContext.cs @@ -0,0 +1,75 @@ +using Microsoft.AspNet.Authentication; +using Microsoft.AspNet.Http; +using Microsoft.AspNet.Http.Authentication; +using System; +using System.Collections.Generic; +using System.Security.Claims; + +namespace OAuth.AspNet.AuthServer +{ + + /// + /// Provides context information used when processing an OAuth token request. + /// + public class OAuthTokenEndpointContext : BaseOAuthEndpointContext + { + /// + /// Initializes a new instance of the class + /// + /// + /// + /// + /// + public OAuthTokenEndpointContext(HttpContext context, OAuthAuthorizationServerOptions options, AuthenticationTicket ticket, TokenEndpointRequest tokenEndpointRequest) : base(context, options) + { + if (ticket == null) + { + throw new ArgumentNullException("ticket"); + } + + Principal = ticket.Principal; + Properties = ticket.Properties; + TokenEndpointRequest = tokenEndpointRequest; + AdditionalResponseParameters = new Dictionary(StringComparer.Ordinal); + TokenIssued = Principal != null; + } + + /// + /// Gets the identity of the resource owner. + /// + public ClaimsPrincipal Principal { get; private set; } + + /// + /// Dictionary containing the state of the authentication session. + /// + public AuthenticationProperties Properties { get; private set; } + + /// + /// Gets information about the token endpoint request. + /// + public TokenEndpointRequest TokenEndpointRequest { get; set; } + + /// + /// Gets whether or not the token should be issued. + /// + public bool TokenIssued { get; private set; } + + /// + /// Enables additional values to be appended to the token response. + /// + public IDictionary AdditionalResponseParameters { get; private set; } + + /// + /// Issues the token. + /// + /// + /// + public void Issue(ClaimsPrincipal principal, AuthenticationProperties properties) + { + Principal = principal; + Properties = properties; + TokenIssued = true; + } + } + +} diff --git a/Yavsc/Auth/AuthServer/OAuthTokenEndpointResponseContext.cs b/Yavsc/Auth/AuthServer/OAuthTokenEndpointResponseContext.cs new file mode 100644 index 00000000..54b03de1 --- /dev/null +++ b/Yavsc/Auth/AuthServer/OAuthTokenEndpointResponseContext.cs @@ -0,0 +1,82 @@ +using Microsoft.AspNet.Authentication; +using Microsoft.AspNet.Http; +using Microsoft.AspNet.Http.Authentication; +using System; +using System.Collections.Generic; +using System.Security.Claims; + +namespace OAuth.AspNet.AuthServer +{ + + /// + /// Provides context information used at the end of a token-endpoint-request. + /// + public class OAuthTokenEndpointResponseContext : BaseOAuthEndpointContext + { + /// + /// Initializes a new instance of the class + /// + /// + /// + /// + /// + public OAuthTokenEndpointResponseContext(HttpContext context, OAuthAuthorizationServerOptions options, AuthenticationTicket ticket, TokenEndpointRequest tokenEndpointRequest, string accessToken, IDictionary additionalResponseParameters) : base(context, options) + { + if (ticket == null) + { + throw new ArgumentNullException("ticket"); + } + + Principal = ticket.Principal; + Properties = ticket.Properties; + TokenEndpointRequest = tokenEndpointRequest; + AdditionalResponseParameters = new Dictionary(StringComparer.Ordinal); + TokenIssued = Principal != null; + AccessToken = accessToken; + AdditionalResponseParameters = additionalResponseParameters; + } + + /// + /// Gets the identity of the resource owner. + /// + public ClaimsPrincipal Principal { get; private set; } + + /// + /// Dictionary containing the state of the authentication session. + /// + public AuthenticationProperties Properties { get; private set; } + + /// + /// The issued Access-Token + /// + public string AccessToken { get; private set; } + + /// + /// Gets information about the token endpoint request. + /// + public TokenEndpointRequest TokenEndpointRequest { get; set; } + + /// + /// Gets whether or not the token should be issued. + /// + public bool TokenIssued { get; private set; } + + /// + /// Enables additional values to be appended to the token response. + /// + public IDictionary AdditionalResponseParameters { get; private set; } + + /// + /// Issues the token. + /// + /// + /// + public void Issue(ClaimsPrincipal principal, AuthenticationProperties properties) + { + Principal = principal; + Properties = properties; + TokenIssued = true; + } + } + +} diff --git a/Yavsc/Auth/AuthServer/OAuthValidateAuthorizeRequestContext.cs b/Yavsc/Auth/AuthServer/OAuthValidateAuthorizeRequestContext.cs new file mode 100644 index 00000000..034f8a87 --- /dev/null +++ b/Yavsc/Auth/AuthServer/OAuthValidateAuthorizeRequestContext.cs @@ -0,0 +1,35 @@ +using Microsoft.AspNet.Http; + +namespace OAuth.AspNet.AuthServer +{ + + /// + /// Provides context information used in validating an OAuth authorization request. + /// + public class OAuthValidateAuthorizeRequestContext : BaseValidatingContext + { + /// + /// Initializes a new instance of the class + /// + /// + /// + /// + /// + public OAuthValidateAuthorizeRequestContext(HttpContext context, OAuthAuthorizationServerOptions options, AuthorizeEndpointRequest authorizeRequest, OAuthValidateClientRedirectUriContext clientContext) : base(context, options) + { + AuthorizeRequest = authorizeRequest; + ClientContext = clientContext; + } + + /// + /// Gets OAuth authorization request data. + /// + public AuthorizeEndpointRequest AuthorizeRequest { get; private set; } + + /// + /// Gets data about the OAuth client. + /// + public OAuthValidateClientRedirectUriContext ClientContext { get; private set; } + } + +} diff --git a/Yavsc/Auth/AuthServer/OAuthValidateClientAuthenticationContext.cs b/Yavsc/Auth/AuthServer/OAuthValidateClientAuthenticationContext.cs new file mode 100644 index 00000000..25127475 --- /dev/null +++ b/Yavsc/Auth/AuthServer/OAuthValidateClientAuthenticationContext.cs @@ -0,0 +1,108 @@ +using Microsoft.AspNet.Http; +using System; +using System.Text; + +namespace OAuth.AspNet.AuthServer +{ + + /// + /// Contains information about the client credentials. + /// + public class OAuthValidateClientAuthenticationContext : BaseValidatingClientContext + { + /// + /// Initializes a new instance of the class + /// + /// + /// + /// + public OAuthValidateClientAuthenticationContext(HttpContext context, OAuthAuthorizationServerOptions options, IReadableStringCollection parameters, IApplicationStore applicationStore) : base(context, options, null) + { + Parameters = parameters; + ApplicationStore = applicationStore; + } + + public IApplicationStore ApplicationStore { get; private set;} + + /// + /// Gets the set of form parameters from the request. + /// + public IReadableStringCollection Parameters { get; private set; } + + /// + /// Sets the client id and marks the context as validated by the application. + /// + /// + /// + public bool Validated(string clientId) + { + ClientId = clientId; + + return Validated(); + } + + /// + /// Extracts HTTP basic authentication credentials from the HTTP authenticate header. + /// + /// + /// + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "0#", Justification = "Optimized for usage")] + public bool TryGetBasicCredentials(out string clientId, out string clientSecret) + { + // Client Authentication http://tools.ietf.org/html/rfc6749#section-2.3 + // Client Authentication Password http://tools.ietf.org/html/rfc6749#section-2.3.1 + string authorization = Request.Headers["Authorization"]; + if (!string.IsNullOrWhiteSpace(authorization) && authorization.StartsWith("Basic ", StringComparison.OrdinalIgnoreCase)) + { + try + { + byte[] data = Convert.FromBase64String(authorization.Substring("Basic ".Length).Trim()); + string text = Encoding.UTF8.GetString(data); + int delimiterIndex = text.IndexOf(':'); + if (delimiterIndex >= 0) + { + clientId = text.Substring(0, delimiterIndex); + clientSecret = text.Substring(delimiterIndex + 1); + ClientId = clientId; + return true; + } + } + catch (FormatException) + { + // Bad Base64 string + } + catch (ArgumentException) + { + // Bad utf-8 string + } + } + + clientId = null; + clientSecret = null; + return false; + } + + /// + /// Extracts forms authentication credentials from the HTTP request body. + /// + /// + /// + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "0#", Justification = "Optimized for usage")] + public bool TryGetFormCredentials(out string clientId, out string clientSecret) + { + clientId = Parameters[Constants.Parameters.ClientId]; + if (!string.IsNullOrEmpty(clientId)) + { + clientSecret = Parameters[Constants.Parameters.ClientSecret]; + ClientId = clientId; + return true; + } + clientId = null; + clientSecret = null; + return false; + } + } + +} diff --git a/Yavsc/Auth/AuthServer/OAuthValidateClientCredentialsContext.cs b/Yavsc/Auth/AuthServer/OAuthValidateClientCredentialsContext.cs new file mode 100644 index 00000000..fa37f10e --- /dev/null +++ b/Yavsc/Auth/AuthServer/OAuthValidateClientCredentialsContext.cs @@ -0,0 +1,14 @@ + + +public class OAuthValidateClientCredentialsContext {  + public OAuthValidateClientCredentialsContext(string clientId,string clientSecret,IApplicationStore applicationStore) + { + ClientId = clientId; + ClientSecret = clientSecret; + ApplicationStore = applicationStore; + } + public string ClientId { get; private set; } + public string ClientSecret { get; private set; } + public IApplicationStore ApplicationStore { get; private set; } + +} \ No newline at end of file diff --git a/Yavsc/Auth/AuthServer/OAuthValidateClientRedirectUriContext.cs b/Yavsc/Auth/AuthServer/OAuthValidateClientRedirectUriContext.cs new file mode 100644 index 00000000..b0e10efd --- /dev/null +++ b/Yavsc/Auth/AuthServer/OAuthValidateClientRedirectUriContext.cs @@ -0,0 +1,74 @@ +using Microsoft.AspNet.Http; +using System; + +namespace OAuth.AspNet.AuthServer +{ + + /// + /// Contains data about the OAuth client redirect URI + /// + public class OAuthValidateClientRedirectUriContext : BaseValidatingClientContext + { + /// + /// Initializes a new instance of the class + /// + /// + /// + /// + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "3#", Justification = "redirect_uri is a string parameter")] + public OAuthValidateClientRedirectUriContext(IApplicationStore applicationStore, HttpContext context, OAuthAuthorizationServerOptions options, string clientId, string redirectUri) : base(context, options, clientId) + { + RedirectUri = redirectUri; + ApplicationStore = applicationStore; + } + + /// + /// Gets the client redirect URI + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1056:UriPropertiesShouldNotBeStrings", Justification = "redirect_uri is a string parameter")] + public string RedirectUri { get; private set; } + + public IApplicationStore ApplicationStore { get; private set;} + + /// + /// Marks this context as validated by the application. IsValidated becomes true and HasError becomes false as a result of calling. + /// + /// + public override bool Validated() + { + if (string.IsNullOrEmpty(RedirectUri)) + { + // Don't allow default validation when redirect_uri not provided with request + return false; + } + return base.Validated(); + } + + /// + /// Checks the redirect URI to determine whether it equals . + /// + /// + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "0#", Justification = "redirect_uri is a string parameter")] + public bool Validated(string redirectUri) + { + if (redirectUri == null) + { + throw new ArgumentNullException("redirectUri"); + } + + if (!string.IsNullOrEmpty(RedirectUri) && + !string.Equals(RedirectUri, redirectUri, StringComparison.Ordinal)) + { + // Don't allow validation to alter redirect_uri provided with request + return false; + } + + RedirectUri = redirectUri; + + return Validated(); + } + } + +} diff --git a/Yavsc/Auth/AuthServer/OAuthValidateTokenRequestContext.cs b/Yavsc/Auth/AuthServer/OAuthValidateTokenRequestContext.cs new file mode 100644 index 00000000..7c2c9703 --- /dev/null +++ b/Yavsc/Auth/AuthServer/OAuthValidateTokenRequestContext.cs @@ -0,0 +1,35 @@ +using Microsoft.AspNet.Http; + +namespace OAuth.AspNet.AuthServer +{ + + /// + /// Provides context information used in validating an OAuth token request. + /// + public class OAuthValidateTokenRequestContext : BaseValidatingContext + { + /// + /// Initializes a new instance of the class + /// + /// + /// + /// + /// + public OAuthValidateTokenRequestContext(HttpContext context, OAuthAuthorizationServerOptions options, TokenEndpointRequest tokenRequest, BaseValidatingClientContext clientContext) : base(context, options) + { + TokenRequest = tokenRequest; + ClientContext = clientContext; + } + + /// + /// Gets the token request data. + /// + public TokenEndpointRequest TokenRequest { get; private set; } + + /// + /// Gets information about the client. + /// + public BaseValidatingClientContext ClientContext { get; private set; } + } + +} diff --git a/Yavsc/Auth/AuthServer/TokenEndpointRequest.cs b/Yavsc/Auth/AuthServer/TokenEndpointRequest.cs new file mode 100644 index 00000000..e60969c0 --- /dev/null +++ b/Yavsc/Auth/AuthServer/TokenEndpointRequest.cs @@ -0,0 +1,160 @@ +using Microsoft.AspNet.Http; +using System; + +namespace OAuth.AspNet.AuthServer +{ + + /// + /// Data object representing the information contained in form encoded body of a Token endpoint request. + /// + public class TokenEndpointRequest + { + /// + /// Creates a new instance populated with values from the form encoded body parameters. + /// + /// Form encoded body parameters from a request. + public TokenEndpointRequest(IReadableStringCollection parameters) + { + if (parameters == null) + { + throw new ArgumentNullException("parameters"); + } + + Parameters = parameters; + GrantType = parameters[Constants.Parameters.GrantType]; + ClientId = parameters[Constants.Parameters.ClientId]; + if (string.Equals(GrantType, Constants.GrantTypes.AuthorizationCode, StringComparison.Ordinal)) + { + AuthorizationCodeGrant = new TokenEndpointRequestAuthorizationCode + { + Code = parameters[Constants.Parameters.Code], + RedirectUri = parameters[Constants.Parameters.RedirectUri], + }; + } + else if (string.Equals(GrantType, Constants.GrantTypes.ClientCredentials, StringComparison.Ordinal)) + { + ClientCredentialsGrant = new TokenEndpointRequestClientCredentials + { + Scope = ((string)parameters[Constants.Parameters.Scope] ?? string.Empty).Split(' ') + }; + } + else if (string.Equals(GrantType, Constants.GrantTypes.RefreshToken, StringComparison.Ordinal)) + { + RefreshTokenGrant = new TokenEndpointRequestRefreshToken + { + RefreshToken = parameters[Constants.Parameters.RefreshToken], + Scope = ((string)parameters[Constants.Parameters.Scope] ?? string.Empty).Split(' ') + }; + } + else if (string.Equals(GrantType, Constants.GrantTypes.Password, StringComparison.Ordinal)) + { + ResourceOwnerPasswordCredentialsGrant = new TokenEndpointRequestResourceOwnerPasswordCredentials + { + UserName = parameters[Constants.Parameters.Username], + Password = parameters[Constants.Parameters.Password], + Scope = ((string)parameters[Constants.Parameters.Scope] ?? string.Empty).Split(' ') + }; + } + else if (!string.IsNullOrEmpty(GrantType)) + { + CustomExtensionGrant = new TokenEndpointRequestCustomExtension + { + Parameters = parameters, + }; + } + } + + /// + /// The form encoded body parameters of the Token endpoint request + /// + public IReadableStringCollection Parameters { get; private set; } + + /// + /// The "grant_type" parameter of the Token endpoint request. This parameter is required. + /// + public string GrantType { get; private set; } + + /// + /// The "client_id" parameter of the Token endpoint request. This parameter is optional. It might not + /// be present if the request is authenticated in a different way, for example, by using basic authentication + /// credentials. + /// + public string ClientId { get; private set; } + + /// + /// Data object available when the "grant_type" is "authorization_code". + /// See also http://tools.ietf.org/html/rfc6749#section-4.1.3 + /// + public TokenEndpointRequestAuthorizationCode AuthorizationCodeGrant { get; private set; } + + /// + /// Data object available when the "grant_type" is "client_credentials". + /// See also http://tools.ietf.org/html/rfc6749#section-4.4.2 + /// + public TokenEndpointRequestClientCredentials ClientCredentialsGrant { get; private set; } + + /// + /// Data object available when the "grant_type" is "refresh_token". + /// See also http://tools.ietf.org/html/rfc6749#section-6 + /// + public TokenEndpointRequestRefreshToken RefreshTokenGrant { get; private set; } + + /// + /// Data object available when the "grant_type" is "password". + /// See also http://tools.ietf.org/html/rfc6749#section-4.3.2 + /// + public TokenEndpointRequestResourceOwnerPasswordCredentials ResourceOwnerPasswordCredentialsGrant { get; private set; } + + /// + /// Data object available when the "grant_type" is unrecognized. + /// See also http://tools.ietf.org/html/rfc6749#section-4.5 + /// + public TokenEndpointRequestCustomExtension CustomExtensionGrant { get; private set; } + + /// + /// True when the "grant_type" is "authorization_code". + /// See also http://tools.ietf.org/html/rfc6749#section-4.1.3 + /// + public bool IsAuthorizationCodeGrantType + { + get { return AuthorizationCodeGrant != null; } + } + + /// + /// True when the "grant_type" is "client_credentials". + /// See also http://tools.ietf.org/html/rfc6749#section-4.4.2 + /// + public bool IsClientCredentialsGrantType + { + get { return ClientCredentialsGrant != null; } + } + + /// + /// True when the "grant_type" is "refresh_token". + /// See also http://tools.ietf.org/html/rfc6749#section-6 + /// + public bool IsRefreshTokenGrantType + { + get { return RefreshTokenGrant != null; } + } + + /// + /// True when the "grant_type" is "password". + /// See also http://tools.ietf.org/html/rfc6749#section-4.3.2 + /// + public bool IsResourceOwnerPasswordCredentialsGrantType + { + get { return ResourceOwnerPasswordCredentialsGrant != null; } + } + + /// + /// True when the "grant_type" is unrecognized. + /// See also http://tools.ietf.org/html/rfc6749#section-4.5 + /// + public bool IsCustomExtensionGrantType + { + get { return CustomExtensionGrant != null; } + } + } + +} diff --git a/Yavsc/Auth/AuthServer/TokenEndpointRequestAuthorizationCode.cs b/Yavsc/Auth/AuthServer/TokenEndpointRequestAuthorizationCode.cs new file mode 100644 index 00000000..f6ab3780 --- /dev/null +++ b/Yavsc/Auth/AuthServer/TokenEndpointRequestAuthorizationCode.cs @@ -0,0 +1,23 @@ + +namespace OAuth.AspNet.AuthServer +{ + + /// + /// Data object used by TokenEndpointRequest when the "grant_type" is "authorization_code". + /// + public class TokenEndpointRequestAuthorizationCode + { + /// + /// The value passed to the Token endpoint in the "code" parameter + /// + public string Code { get; set; } + + /// + /// The value passed to the Token endpoint in the "redirect_uri" parameter. This MUST be provided by the caller + /// if the original visit to the Authorize endpoint contained a "redirect_uri" parameter. + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1056:UriPropertiesShouldNotBeStrings", Justification = "By design")] + public string RedirectUri { get; set; } + } + +} diff --git a/Yavsc/Auth/AuthServer/TokenEndpointRequestClientCredentials.cs b/Yavsc/Auth/AuthServer/TokenEndpointRequestClientCredentials.cs new file mode 100644 index 00000000..1f116ecc --- /dev/null +++ b/Yavsc/Auth/AuthServer/TokenEndpointRequestClientCredentials.cs @@ -0,0 +1,18 @@ +using System.Collections.Generic; + +namespace OAuth.AspNet.AuthServer +{ + + /// + /// Data object used by TokenEndpointRequest when the "grant_type" is "client_credentials". + /// + public class TokenEndpointRequestClientCredentials + { + /// + /// The value passed to the Token endpoint in the "scope" parameter + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Justification = "This class is just for passing data through.")] + public IList Scope { get; set; } + } + +} diff --git a/Yavsc/Auth/AuthServer/TokenEndpointRequestCustomExtension.cs b/Yavsc/Auth/AuthServer/TokenEndpointRequestCustomExtension.cs new file mode 100644 index 00000000..2664b3d1 --- /dev/null +++ b/Yavsc/Auth/AuthServer/TokenEndpointRequestCustomExtension.cs @@ -0,0 +1,17 @@ +using Microsoft.AspNet.Http; + +namespace OAuth.AspNet.AuthServer +{ + + /// + /// Data object used by TokenEndpointRequest which contains parameter information when the "grant_type" is unrecognized. + /// + public class TokenEndpointRequestCustomExtension + { + /// + /// The parameter information when the "grant_type" is unrecognized. + /// + public IReadableStringCollection Parameters { get; set; } + } + +} diff --git a/Yavsc/Auth/AuthServer/TokenEndpointRequestRefreshToken.cs b/Yavsc/Auth/AuthServer/TokenEndpointRequestRefreshToken.cs new file mode 100644 index 00000000..484a37ce --- /dev/null +++ b/Yavsc/Auth/AuthServer/TokenEndpointRequestRefreshToken.cs @@ -0,0 +1,21 @@ +using System.Collections.Generic; + +namespace OAuth.AspNet.AuthServer +{ + /// + /// Data object used by TokenEndpointRequest when the "grant_type" parameter is "refresh_token". + /// + public class TokenEndpointRequestRefreshToken + { + /// + /// The value passed to the Token endpoint in the "refresh_token" parameter + /// + public string RefreshToken { get; set; } + + /// + /// The value passed to the Token endpoint in the "scope" parameter + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Justification = "This is just a data container object.")] + public IList Scope { get; set; } + } +} diff --git a/Yavsc/Auth/AuthServer/TokenEndpointRequestResourceOwnerPasswordCredentials.cs b/Yavsc/Auth/AuthServer/TokenEndpointRequestResourceOwnerPasswordCredentials.cs new file mode 100644 index 00000000..bde4ff2f --- /dev/null +++ b/Yavsc/Auth/AuthServer/TokenEndpointRequestResourceOwnerPasswordCredentials.cs @@ -0,0 +1,26 @@ +using System.Collections.Generic; + +namespace OAuth.AspNet.AuthServer +{ + /// + /// Data object used by TokenEndpointRequest when the "grant_type" is "password". + /// + public class TokenEndpointRequestResourceOwnerPasswordCredentials + { + /// + /// The value passed to the Token endpoint in the "username" parameter + /// + public string UserName { get; set; } + + /// + /// The value passed to the Token endpoint in the "password" parameter + /// + public string Password { get; set; } + + /// + /// The value passed to the Token endpoint in the "scope" parameter + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Justification = "This is just a data class.")] + public IList Scope { get; set; } + } +} diff --git a/Yavsc/Auth/AuthServer/Tokens/TicketDataFormatTokenValidator.cs b/Yavsc/Auth/AuthServer/Tokens/TicketDataFormatTokenValidator.cs new file mode 100644 index 00000000..586e1c6e --- /dev/null +++ b/Yavsc/Auth/AuthServer/Tokens/TicketDataFormatTokenValidator.cs @@ -0,0 +1,93 @@ +using Microsoft.AspNet.Authentication; +using Microsoft.AspNet.DataProtection; +using System; +using System.IdentityModel.Tokens; +using System.Security.Claims; +using System.Text.RegularExpressions; +using Yavsc.Auth; +using Yavsc; + +namespace OAuth.AspNet.Tokens +{ + + public class TicketDataFormatTokenValidator : ISecurityTokenValidator + { + #region Constructors + + public TicketDataFormatTokenValidator() : this(null) { } + + public TicketDataFormatTokenValidator(IDataProtectionProvider dataProtectionProvider) + { + if (dataProtectionProvider == null) + { + dataProtectionProvider = new MonoDataProtectionProvider(Constants.ApplicationName) + .CreateProtector(Constants.KeyProtectorPurpose); + } + _ticketDataFormat = new TicketDataFormat(dataProtectionProvider.CreateProtector("Access_Token", "v1")); + } + + #endregion + + #region non-Public Members + + private TicketDataFormat _ticketDataFormat; + + private const string _serializationRegex = @"^[A-Za-z0-9-_]*$"; + + private int _maximumTokenSizeInBytes = TokenValidationParameters.DefaultMaximumTokenSizeInBytes; + + #endregion + + #region Public Members + + public bool CanValidateToken + { + get + { + return true; + } + } + + public int MaximumTokenSizeInBytes + { + get + { + return _maximumTokenSizeInBytes; + } + + set + { + if (value < 1) + throw new ArgumentOutOfRangeException(nameof(MaximumTokenSizeInBytes), "Negative or zero-sized tokens are invalid."); + + _maximumTokenSizeInBytes = value; + } + } + + public bool CanReadToken(string securityToken) + { + if (string.IsNullOrWhiteSpace(securityToken)) + throw new ArgumentException("Security token has no value.", nameof(securityToken)); + + if (securityToken.Length * 2 > this.MaximumTokenSizeInBytes) + return false; + + if (Regex.IsMatch(securityToken, _serializationRegex)) + return true; + + return false; + } + + public ClaimsPrincipal ValidateToken(string securityToken, TokenValidationParameters validationParameters, out SecurityToken validatedToken) + { + AuthenticationTicket ticket = _ticketDataFormat.Unprotect(securityToken); + + validatedToken = null; + + return ticket?.Principal; + } + + #endregion + } + +} diff --git a/Yavsc/src/Auth/GoogleExtensions.cs b/Yavsc/Auth/GoogleExtensions.cs similarity index 100% rename from Yavsc/src/Auth/GoogleExtensions.cs rename to Yavsc/Auth/GoogleExtensions.cs diff --git a/Yavsc/src/Auth/GoogleHandler.cs b/Yavsc/Auth/GoogleHandler.cs similarity index 100% rename from Yavsc/src/Auth/GoogleHandler.cs rename to Yavsc/Auth/GoogleHandler.cs diff --git a/Yavsc/src/Auth/GoogleHelper.cs b/Yavsc/Auth/GoogleHelper.cs similarity index 100% rename from Yavsc/src/Auth/GoogleHelper.cs rename to Yavsc/Auth/GoogleHelper.cs diff --git a/Yavsc/src/Auth/GoogleMiddleWare.cs b/Yavsc/Auth/GoogleMiddleWare.cs similarity index 100% rename from Yavsc/src/Auth/GoogleMiddleWare.cs rename to Yavsc/Auth/GoogleMiddleWare.cs diff --git a/Yavsc/src/Auth/GoogleOAuthCreatingTicket.cs b/Yavsc/Auth/GoogleOAuthCreatingTicket.cs similarity index 100% rename from Yavsc/src/Auth/GoogleOAuthCreatingTicket.cs rename to Yavsc/Auth/GoogleOAuthCreatingTicket.cs diff --git a/Yavsc/src/Auth/GoogleOptions.cs b/Yavsc/Auth/GoogleOptions.cs similarity index 100% rename from Yavsc/src/Auth/GoogleOptions.cs rename to Yavsc/Auth/GoogleOptions.cs diff --git a/Yavsc/src/Auth/MonoDataProtectionProvider.cs b/Yavsc/Auth/MonoDataProtectionProvider.cs similarity index 100% rename from Yavsc/src/Auth/MonoDataProtectionProvider.cs rename to Yavsc/Auth/MonoDataProtectionProvider.cs diff --git a/Yavsc/src/Auth/MonoDataProtector.cs b/Yavsc/Auth/MonoDataProtector.cs similarity index 100% rename from Yavsc/src/Auth/MonoDataProtector.cs rename to Yavsc/Auth/MonoDataProtector.cs diff --git a/Yavsc/src/Auth/MonoJwtSecurityTokenHandler.cs b/Yavsc/Auth/MonoJwtSecurityTokenHandler.cs similarity index 100% rename from Yavsc/src/Auth/MonoJwtSecurityTokenHandler.cs rename to Yavsc/Auth/MonoJwtSecurityTokenHandler.cs diff --git a/Yavsc/src/Auth/RSAKeyUtils.cs b/Yavsc/Auth/RSAKeyUtils.cs similarity index 100% rename from Yavsc/src/Auth/RSAKeyUtils.cs rename to Yavsc/Auth/RSAKeyUtils.cs diff --git a/Yavsc/src/Auth/RequiredScopesMiddleware.cs b/Yavsc/Auth/RequiredScopesMiddleware.cs similarity index 100% rename from Yavsc/src/Auth/RequiredScopesMiddleware.cs rename to Yavsc/Auth/RequiredScopesMiddleware.cs diff --git a/Yavsc/src/Auth/TokenAuthOptions.cs b/Yavsc/Auth/TokenAuthOptions.cs similarity index 100% rename from Yavsc/src/Auth/TokenAuthOptions.cs rename to Yavsc/Auth/TokenAuthOptions.cs diff --git a/Yavsc/src/Auth/UserTokenProvider.cs b/Yavsc/Auth/UserTokenProvider.cs similarity index 100% rename from Yavsc/src/Auth/UserTokenProvider.cs rename to Yavsc/Auth/UserTokenProvider.cs diff --git a/Yavsc/src/Auth/XmlEncryptor.cs b/Yavsc/Auth/XmlEncryptor.cs similarity index 100% rename from Yavsc/src/Auth/XmlEncryptor.cs rename to Yavsc/Auth/XmlEncryptor.cs diff --git a/Yavsc/src/Auth/Yavsc/YavscAuthenticationHandler.cs b/Yavsc/Auth/Yavsc/YavscAuthenticationHandler.cs similarity index 100% rename from Yavsc/src/Auth/Yavsc/YavscAuthenticationHandler.cs rename to Yavsc/Auth/Yavsc/YavscAuthenticationHandler.cs diff --git a/Yavsc/src/Auth/Yavsc/YavscAuthenticationMiddleware.cs b/Yavsc/Auth/Yavsc/YavscAuthenticationMiddleware.cs similarity index 100% rename from Yavsc/src/Auth/Yavsc/YavscAuthenticationMiddleware.cs rename to Yavsc/Auth/Yavsc/YavscAuthenticationMiddleware.cs diff --git a/Yavsc/src/Auth/Yavsc/YavscAuthenticationMiddlewareOptions.cs b/Yavsc/Auth/Yavsc/YavscAuthenticationMiddlewareOptions.cs similarity index 100% rename from Yavsc/src/Auth/Yavsc/YavscAuthenticationMiddlewareOptions.cs rename to Yavsc/Auth/Yavsc/YavscAuthenticationMiddlewareOptions.cs diff --git a/Yavsc/src/Constants.cs b/Yavsc/Constants.cs similarity index 91% rename from Yavsc/src/Constants.cs rename to Yavsc/Constants.cs index 99f759b9..7405d06f 100644 --- a/Yavsc/src/Constants.cs +++ b/Yavsc/Constants.cs @@ -39,5 +39,11 @@ namespace Yavsc public const string CompanyClaimType = "https://schemas.pschneider.fr/identity/claims/Company"; public const string UserNameRegExp = @"^[a-zA-Z][a-zA-Z0-9 ]*$"; + + public const string AuthenticationEndPath = "/signin"; + public const string TokenEndPath = "/token"; + + public const string KeyProtectorPurpose = "OAuth.AspNet.AuthServer"; + } } diff --git a/Yavsc/src/Controllers/AccountController.cs b/Yavsc/Controllers/AccountController.cs similarity index 100% rename from Yavsc/src/Controllers/AccountController.cs rename to Yavsc/Controllers/AccountController.cs diff --git a/Yavsc/src/Controllers/ActivityController.cs b/Yavsc/Controllers/ActivityController.cs similarity index 100% rename from Yavsc/src/Controllers/ActivityController.cs rename to Yavsc/Controllers/ActivityController.cs diff --git a/Yavsc/src/Controllers/AdministrationController.cs b/Yavsc/Controllers/AdministrationController.cs similarity index 100% rename from Yavsc/src/Controllers/AdministrationController.cs rename to Yavsc/Controllers/AdministrationController.cs diff --git a/Yavsc/src/Controllers/ApplicationController.cs b/Yavsc/Controllers/ApplicationController.cs similarity index 95% rename from Yavsc/src/Controllers/ApplicationController.cs rename to Yavsc/Controllers/ApplicationController.cs index abf62500..11d90bcf 100644 --- a/Yavsc/src/Controllers/ApplicationController.cs +++ b/Yavsc/Controllers/ApplicationController.cs @@ -2,6 +2,7 @@ using System; using System.Linq; using Microsoft.AspNet.Authorization; using Microsoft.AspNet.Mvc; +using Microsoft.Data.Entity; using Yavsc.Models; namespace Yavsc.Controllers diff --git a/Yavsc/src/Controllers/BlogspotController.cs b/Yavsc/Controllers/BlogspotController.cs similarity index 100% rename from Yavsc/src/Controllers/BlogspotController.cs rename to Yavsc/Controllers/BlogspotController.cs diff --git a/Yavsc/src/Controllers/CircleController.cs b/Yavsc/Controllers/CircleController.cs similarity index 100% rename from Yavsc/src/Controllers/CircleController.cs rename to Yavsc/Controllers/CircleController.cs diff --git a/Yavsc/src/Controllers/CommandController.cs b/Yavsc/Controllers/CommandController.cs similarity index 100% rename from Yavsc/src/Controllers/CommandController.cs rename to Yavsc/Controllers/CommandController.cs diff --git a/Yavsc/src/Controllers/EstimateController.cs b/Yavsc/Controllers/EstimateController.cs similarity index 100% rename from Yavsc/src/Controllers/EstimateController.cs rename to Yavsc/Controllers/EstimateController.cs diff --git a/Yavsc/src/Controllers/FrontOfficeController.cs b/Yavsc/Controllers/FrontOfficeController.cs similarity index 100% rename from Yavsc/src/Controllers/FrontOfficeController.cs rename to Yavsc/Controllers/FrontOfficeController.cs diff --git a/Yavsc/src/Controllers/HomeController.cs b/Yavsc/Controllers/HomeController.cs similarity index 100% rename from Yavsc/src/Controllers/HomeController.cs rename to Yavsc/Controllers/HomeController.cs diff --git a/Yavsc/src/Controllers/ManageController.cs b/Yavsc/Controllers/ManageController.cs similarity index 100% rename from Yavsc/src/Controllers/ManageController.cs rename to Yavsc/Controllers/ManageController.cs diff --git a/Yavsc/Controllers/OAuthController.cs b/Yavsc/Controllers/OAuthController.cs new file mode 100644 index 00000000..22280ba1 --- /dev/null +++ b/Yavsc/Controllers/OAuthController.cs @@ -0,0 +1,158 @@ +using System; +using System.Linq; +using System.Security.Claims; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.AspNet.Authentication; +using Microsoft.AspNet.Authorization; +using Microsoft.AspNet.Builder; +using Microsoft.AspNet.DataProtection.KeyManagement; +using Microsoft.AspNet.Http.Authentication; +using Microsoft.AspNet.Identity; +using Microsoft.AspNet.Mvc; +using Microsoft.Data.Entity; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.OptionsModel; +using Microsoft.IdentityModel.Protocols.OpenIdConnect; +using Yavsc.Extensions; +using Yavsc.Models; +using Yavsc.ViewModels.Account; + +namespace Yavsc.Controllers +{ + [AllowAnonymous] + public class OAuthController : Controller + { + ApplicationDbContext _context; + UserManager _userManager; + + SiteSettings _siteSettings; + + ILogger _logger; + private readonly SignInManager _signInManager; + private TokenAuthOptions _tokenOptions; + + public OAuthController(ApplicationDbContext context, SignInManager signInManager, IKeyManager keyManager, + IOptions tokenOptions, + UserManager userManager, + IOptions siteSettings, + ILoggerFactory loggerFactory + ) + { + _siteSettings = siteSettings.Value; + _context = context; + _signInManager = signInManager; + _tokenOptions = tokenOptions.Value; + _userManager = userManager; + _logger = loggerFactory.CreateLogger(); + } + + + [HttpGet("~/signin")] + public ActionResult SignIn(string returnUrl = null) + { + _logger.LogWarning($"Singin wanted: returnUrl: {returnUrl} "); + // Note: the "returnUrl" parameter corresponds to the endpoint the user agent + // will be redirected to after a successful authentication and not + // the redirect_uri of the requesting client application. + return View("SignIn", new LoginViewModel + { + ReturnUrl = returnUrl, + ExternalProviders = HttpContext.GetExternalProviders() + }); + /* Note: When using an external login provider, redirect the query : + var properties = _signInManager.ConfigureExternalAuthenticationProperties(OpenIdConnectDefaults.AuthenticationScheme, returnUrl); + return new ChallengeResult(OpenIdConnectDefaults.AuthenticationScheme, properties); + */ + } + + [HttpGet("~/authenticate")] + public ActionResult Authenticate(string returnUrl = null) + { + return SignIn(returnUrl); + } + + [HttpGet("~/forbidden")] + public ActionResult Forbidden(string returnUrl = null) + { + return View("Forbidden",returnUrl); + } + + [HttpPost("~/signin")] + public IActionResult SignIn(string Provider, string ReturnUrl) + { + // Note: the "provider" parameter corresponds to the external + // authentication provider choosen by the user agent. + if (string.IsNullOrEmpty(Provider)) + { + _logger.LogWarning("Provider not specified"); + return HttpBadRequest(); + } + + if (!_signInManager.GetExternalAuthenticationSchemes().Any(x => x.AuthenticationScheme == Provider)) + { + _logger.LogWarning($"Provider not found : {Provider}"); + return HttpBadRequest(); + } + + // Instruct the middleware corresponding to the requested external identity + // provider to redirect the user agent to its own authorization endpoint. + // Note: the authenticationScheme parameter must match the value configured in Startup.cs + + // Note: the "returnUrl" parameter corresponds to the endpoint the user agent + // will be redirected to after a successful authentication and not + // the redirect_uri of the requesting client application. + if (string.IsNullOrEmpty(ReturnUrl)) + { + _logger.LogWarning("ReturnUrl not specified"); + return HttpBadRequest(); + } + var redirectUrl = Url.Action("ExternalLoginCallback", "Account", new { ReturnUrl = ReturnUrl }); + var properties = _signInManager.ConfigureExternalAuthenticationProperties(Provider, redirectUrl); + // var properties = new AuthenticationProperties{RedirectUri=ReturnUrl}; + return new ChallengeResult(Provider,properties); + } + + + + [HttpGet("~/signout"), HttpPost("~/signout")] + public async Task SignOut() + { + // Instruct the cookies middleware to delete the local cookie created + // when the user agent is redirected from the external identity provider + // after a successful authentication flow (e.g Google or Facebook). + + await HttpContext.Authentication.SignOutAsync("ServerCookie"); + } + + + + + [HttpGet("~/api/getclaims"), Produces("application/json")] + + public IActionResult GetClaims() + { + var identity = User.Identity as ClaimsIdentity; + + var claims = from c in identity.Claims + select new + { + subject = c.Subject.Name, + type = c.Type, + value = c.Value + }; + + return Ok(claims); + } + + protected virtual Task GetApplicationAsync(string identifier, CancellationToken cancellationToken) + { + // Retrieve the application details corresponding to the requested client_id. + return (from application in _context.Applications + where application.ApplicationID == identifier + select application).SingleOrDefaultAsync(cancellationToken); + } + + + } +} \ No newline at end of file diff --git a/Yavsc/src/Controllers/TokenController.cs b/Yavsc/Controllers/TokenController.cs similarity index 100% rename from Yavsc/src/Controllers/TokenController.cs rename to Yavsc/Controllers/TokenController.cs diff --git a/Yavsc/src/Controllers/UserFilesController.cs b/Yavsc/Controllers/UserFilesController.cs similarity index 100% rename from Yavsc/src/Controllers/UserFilesController.cs rename to Yavsc/Controllers/UserFilesController.cs diff --git a/Yavsc/src/Controllers/ValuesController.cs b/Yavsc/Controllers/ValuesController.cs similarity index 100% rename from Yavsc/src/Controllers/ValuesController.cs rename to Yavsc/Controllers/ValuesController.cs diff --git a/Yavsc/src/Extensions/AppBuilderExtensions.cs b/Yavsc/Extensions/AppBuilderExtensions.cs similarity index 100% rename from Yavsc/src/Extensions/AppBuilderExtensions.cs rename to Yavsc/Extensions/AppBuilderExtensions.cs diff --git a/Yavsc/Extensions/OAuthAuthorizationServerExtensions.cs b/Yavsc/Extensions/OAuthAuthorizationServerExtensions.cs new file mode 100644 index 00000000..5e43059d --- /dev/null +++ b/Yavsc/Extensions/OAuthAuthorizationServerExtensions.cs @@ -0,0 +1,61 @@ +using System; +using Microsoft.AspNet.Builder; +using OAuth.AspNet.AuthServer; + +namespace Microsoft.AspNet.Builder +{ + + /// + /// Extension methods to add Authorization Server capabilities to an OWIN pipeline + /// + public static class OAuthAuthorizationServerExtensions + { + /// + /// Adds OAuth2 Authorization Server capabilities to an OWIN web application. This middleware + /// performs the request processing for the Authorize and Token endpoints defined by the OAuth2 specification. + /// See also http://tools.ietf.org/html/rfc6749 + /// + /// The web application builder + /// Options which control the behavior of the Authorization Server. + /// The application builder + public static IApplicationBuilder UseOAuthAuthorizationServer(this IApplicationBuilder app, OAuthAuthorizationServerOptions options) + { + if (app == null) + throw new NullReferenceException($"The extension method {nameof(OAuthAuthorizationServerExtensions.UseOAuthAuthorizationServer)} was called on a null reference to a {nameof(IApplicationBuilder)}"); + + if (options == null) + throw new ArgumentNullException(nameof(options)); + + + + return app.UseMiddleware(options); + } + + + /// + /// Adds OAuth2 Authorization Server capabilities to an OWIN web application. This middleware + /// performs the request processing for the Authorize and Token endpoints defined by the OAuth2 specification. + /// See also http://tools.ietf.org/html/rfc6749 + /// + /// The web application builder + /// Options which control the behavior of the Authorization Server. + /// The application builder + public static IApplicationBuilder UseOAuthAuthorizationServer(this IApplicationBuilder app, Action configureOptions) + { + if (app == null) + throw new NullReferenceException($"The extension method {nameof(OAuthAuthorizationServerExtensions.UseOAuthAuthorizationServer)} was called on a null reference to a {nameof(IApplicationBuilder)}"); + + if (configureOptions == null) + throw new ArgumentNullException(nameof(configureOptions)); + + + var options = new OAuthAuthorizationServerOptions(); + if (configureOptions != null) + + configureOptions(options); + + return app.UseOAuthAuthorizationServer(options); + } + } + +} diff --git a/Yavsc/src/Extensions/SignalRBuilderExtension.cs b/Yavsc/Extensions/SignalRBuilderExtension.cs similarity index 100% rename from Yavsc/src/Extensions/SignalRBuilderExtension.cs rename to Yavsc/Extensions/SignalRBuilderExtension.cs diff --git a/Yavsc/src/LanguageActionFilter.cs b/Yavsc/Filters/LanguageActionFilter.cs similarity index 100% rename from Yavsc/src/LanguageActionFilter.cs rename to Yavsc/Filters/LanguageActionFilter.cs diff --git a/Yavsc/src/Formatters/PdfFormatter.cs b/Yavsc/Formatters/PdfFormatter.cs similarity index 100% rename from Yavsc/src/Formatters/PdfFormatter.cs rename to Yavsc/Formatters/PdfFormatter.cs diff --git a/Yavsc/src/GoogleApis/CalendarApi.cs b/Yavsc/GoogleApis/CalendarApi.cs similarity index 100% rename from Yavsc/src/GoogleApis/CalendarApi.cs rename to Yavsc/GoogleApis/CalendarApi.cs diff --git a/Yavsc/src/GoogleApis/MapTracks.cs b/Yavsc/GoogleApis/MapTracks.cs similarity index 100% rename from Yavsc/src/GoogleApis/MapTracks.cs rename to Yavsc/GoogleApis/MapTracks.cs diff --git a/Yavsc/src/GoogleApis/PeopleApi.cs b/Yavsc/GoogleApis/PeopleApi.cs similarity index 100% rename from Yavsc/src/GoogleApis/PeopleApi.cs rename to Yavsc/GoogleApis/PeopleApi.cs diff --git a/Yavsc/src/Helpers/AuthHelpers.cs b/Yavsc/Helpers/AuthHelpers.cs similarity index 100% rename from Yavsc/src/Helpers/AuthHelpers.cs rename to Yavsc/Helpers/AuthHelpers.cs diff --git a/Yavsc/src/Helpers/CompanyInfoHelpers.cs b/Yavsc/Helpers/CompanyInfoHelpers.cs similarity index 100% rename from Yavsc/src/Helpers/CompanyInfoHelpers.cs rename to Yavsc/Helpers/CompanyInfoHelpers.cs diff --git a/Yavsc/src/Helpers/EventHelpers.cs b/Yavsc/Helpers/EventHelpers.cs similarity index 100% rename from Yavsc/src/Helpers/EventHelpers.cs rename to Yavsc/Helpers/EventHelpers.cs diff --git a/Yavsc/src/Helpers/FileSystemHelpers.cs b/Yavsc/Helpers/FileSystemHelpers.cs similarity index 100% rename from Yavsc/src/Helpers/FileSystemHelpers.cs rename to Yavsc/Helpers/FileSystemHelpers.cs diff --git a/Yavsc/src/Helpers/GoogleHelpers.cs b/Yavsc/Helpers/GoogleHelpers.cs similarity index 100% rename from Yavsc/src/Helpers/GoogleHelpers.cs rename to Yavsc/Helpers/GoogleHelpers.cs diff --git a/Yavsc/src/Helpers/ListItemHelpers.cs b/Yavsc/Helpers/ListItemHelpers.cs similarity index 100% rename from Yavsc/src/Helpers/ListItemHelpers.cs rename to Yavsc/Helpers/ListItemHelpers.cs diff --git a/Yavsc/src/Helpers/SimpleJsonPostMethod.cs b/Yavsc/Helpers/SimpleJsonPostMethod.cs similarity index 100% rename from Yavsc/src/Helpers/SimpleJsonPostMethod.cs rename to Yavsc/Helpers/SimpleJsonPostMethod.cs diff --git a/Yavsc/src/Helpers/TagHelpers.cs b/Yavsc/Helpers/TagHelpers.cs similarity index 100% rename from Yavsc/src/Helpers/TagHelpers.cs rename to Yavsc/Helpers/TagHelpers.cs diff --git a/Yavsc/src/Hubs/ChatHub.cs b/Yavsc/Hubs/ChatHub.cs similarity index 100% rename from Yavsc/src/Hubs/ChatHub.cs rename to Yavsc/Hubs/ChatHub.cs diff --git a/Yavsc/src/Interfaces/IDataStore.cs b/Yavsc/Interfaces/IDataStore.cs similarity index 100% rename from Yavsc/src/Interfaces/IDataStore.cs rename to Yavsc/Interfaces/IDataStore.cs diff --git a/Yavsc/src/Interfaces/IIdentified.cs b/Yavsc/Interfaces/IIdentified.cs similarity index 100% rename from Yavsc/src/Interfaces/IIdentified.cs rename to Yavsc/Interfaces/IIdentified.cs diff --git a/Yavsc/src/Interfaces/IPerformerSpecified.cs b/Yavsc/Interfaces/IPerformerSpecified.cs similarity index 100% rename from Yavsc/src/Interfaces/IPerformerSpecified.cs rename to Yavsc/Interfaces/IPerformerSpecified.cs diff --git a/Yavsc/src/Interfaces/IRating.cs b/Yavsc/Interfaces/IRating.cs similarity index 100% rename from Yavsc/src/Interfaces/IRating.cs rename to Yavsc/Interfaces/IRating.cs diff --git a/Yavsc/src/Interfaces/ITitle.cs b/Yavsc/Interfaces/ITitle.cs similarity index 100% rename from Yavsc/src/Interfaces/ITitle.cs rename to Yavsc/Interfaces/ITitle.cs diff --git a/Yavsc/src/Model/Access/PerformerIM.cs b/Yavsc/Model/Access/PerformerIM.cs similarity index 100% rename from Yavsc/src/Model/Access/PerformerIM.cs rename to Yavsc/Model/Access/PerformerIM.cs diff --git a/Yavsc/src/Model/Access/Publishing.cs b/Yavsc/Model/Access/Publishing.cs similarity index 100% rename from Yavsc/src/Model/Access/Publishing.cs rename to Yavsc/Model/Access/Publishing.cs diff --git a/Yavsc/src/Model/Access/Rule.cs b/Yavsc/Model/Access/Rule.cs similarity index 100% rename from Yavsc/src/Model/Access/Rule.cs rename to Yavsc/Model/Access/Rule.cs diff --git a/Yavsc/src/Model/Access/RuleSet.cs b/Yavsc/Model/Access/RuleSet.cs similarity index 100% rename from Yavsc/src/Model/Access/RuleSet.cs rename to Yavsc/Model/Access/RuleSet.cs diff --git a/Yavsc/src/Model/Access/WhiteCard.cs b/Yavsc/Model/Access/WhiteCard.cs similarity index 100% rename from Yavsc/src/Model/Access/WhiteCard.cs rename to Yavsc/Model/Access/WhiteCard.cs diff --git a/Yavsc/src/Model/ApplicationDbContext.cs b/Yavsc/Model/ApplicationDbContext.cs similarity index 93% rename from Yavsc/src/Model/ApplicationDbContext.cs rename to Yavsc/Model/ApplicationDbContext.cs index 9b876f68..875a9baf 100644 --- a/Yavsc/src/Model/ApplicationDbContext.cs +++ b/Yavsc/Model/ApplicationDbContext.cs @@ -10,7 +10,7 @@ using Yavsc.Models.Booking; namespace Yavsc.Models { - public class ApplicationDbContext : IdentityDbContext + public class ApplicationDbContext : IdentityDbContext, IApplicationStore { protected override void OnModelCreating(ModelBuilder builder) { @@ -145,5 +145,11 @@ namespace Yavsc.Models SaveChanges(); return Task.FromResult(0); } + + IApplication IApplicationStore.FindApplication(string clientId) + { + return Applications.FirstOrDefault( + app=>app.ApplicationID == clientId); + } } } diff --git a/Yavsc/src/Model/Auth/Application.cs b/Yavsc/Model/Auth/Application.cs similarity index 88% rename from Yavsc/src/Model/Auth/Application.cs rename to Yavsc/Model/Auth/Application.cs index 6a4fb345..7e6f24b2 100644 --- a/Yavsc/src/Model/Auth/Application.cs +++ b/Yavsc/Model/Auth/Application.cs @@ -2,7 +2,7 @@ using System.ComponentModel.DataAnnotations; namespace Yavsc { - public class Application + public class Application : IApplication { [Key] public string ApplicationID { get; set; } diff --git a/Yavsc/src/Model/Auth/Scope.cs b/Yavsc/Model/Auth/Scope.cs similarity index 100% rename from Yavsc/src/Model/Auth/Scope.cs rename to Yavsc/Model/Auth/Scope.cs diff --git a/Yavsc/src/Model/Auth/UserCredentials.cs b/Yavsc/Model/Auth/UserCredentials.cs similarity index 100% rename from Yavsc/src/Model/Auth/UserCredentials.cs rename to Yavsc/Model/Auth/UserCredentials.cs diff --git a/Yavsc/src/Model/Bank/AccountBalance.cs b/Yavsc/Model/Bank/AccountBalance.cs similarity index 100% rename from Yavsc/src/Model/Bank/AccountBalance.cs rename to Yavsc/Model/Bank/AccountBalance.cs diff --git a/Yavsc/src/Model/Bank/BalanceImpact.cs b/Yavsc/Model/Bank/BalanceImpact.cs similarity index 100% rename from Yavsc/src/Model/Bank/BalanceImpact.cs rename to Yavsc/Model/Bank/BalanceImpact.cs diff --git a/Yavsc/src/Model/Billing/CommandLine.cs b/Yavsc/Model/Billing/CommandLine.cs similarity index 100% rename from Yavsc/src/Model/Billing/CommandLine.cs rename to Yavsc/Model/Billing/CommandLine.cs diff --git a/Yavsc/src/Model/Billing/Commande.cs b/Yavsc/Model/Billing/Commande.cs similarity index 100% rename from Yavsc/src/Model/Billing/Commande.cs rename to Yavsc/Model/Billing/Commande.cs diff --git a/Yavsc/src/Model/Billing/Estimate.cs b/Yavsc/Model/Billing/Estimate.cs similarity index 100% rename from Yavsc/src/Model/Billing/Estimate.cs rename to Yavsc/Model/Billing/Estimate.cs diff --git a/Yavsc/src/Model/Billing/EstimateAgreement.cs b/Yavsc/Model/Billing/EstimateAgreement.cs similarity index 100% rename from Yavsc/src/Model/Billing/EstimateAgreement.cs rename to Yavsc/Model/Billing/EstimateAgreement.cs diff --git a/Yavsc/src/Model/Billing/Service/ChatBilling.cs b/Yavsc/Model/Billing/Service/ChatBilling.cs similarity index 100% rename from Yavsc/src/Model/Billing/Service/ChatBilling.cs rename to Yavsc/Model/Billing/Service/ChatBilling.cs diff --git a/Yavsc/src/Model/Billing/histoestim.cs b/Yavsc/Model/Billing/histoestim.cs similarity index 100% rename from Yavsc/src/Model/Billing/histoestim.cs rename to Yavsc/Model/Billing/histoestim.cs diff --git a/Yavsc/src/Model/Billing/satisfaction.cs b/Yavsc/Model/Billing/satisfaction.cs similarity index 100% rename from Yavsc/src/Model/Billing/satisfaction.cs rename to Yavsc/Model/Billing/satisfaction.cs diff --git a/Yavsc/src/Model/Billing/writtings.cs b/Yavsc/Model/Billing/writtings.cs similarity index 100% rename from Yavsc/src/Model/Billing/writtings.cs rename to Yavsc/Model/Billing/writtings.cs diff --git a/Yavsc/src/Model/Billing/wrtags.cs b/Yavsc/Model/Billing/wrtags.cs similarity index 100% rename from Yavsc/src/Model/Billing/wrtags.cs rename to Yavsc/Model/Billing/wrtags.cs diff --git a/Yavsc/src/Model/Blog/Blog.cs b/Yavsc/Model/Blog/Blog.cs similarity index 100% rename from Yavsc/src/Model/Blog/Blog.cs rename to Yavsc/Model/Blog/Blog.cs diff --git a/Yavsc/src/Model/Blog/BlogAccess.cs b/Yavsc/Model/Blog/BlogAccess.cs similarity index 100% rename from Yavsc/src/Model/Blog/BlogAccess.cs rename to Yavsc/Model/Blog/BlogAccess.cs diff --git a/Yavsc/src/Model/Blog/IBlogspotRepository.cs b/Yavsc/Model/Blog/IBlogspotRepository.cs similarity index 100% rename from Yavsc/src/Model/Blog/IBlogspotRepository.cs rename to Yavsc/Model/Blog/IBlogspotRepository.cs diff --git a/Yavsc/src/Model/Blog/comment.cs b/Yavsc/Model/Blog/comment.cs similarity index 100% rename from Yavsc/src/Model/Blog/comment.cs rename to Yavsc/Model/Blog/comment.cs diff --git a/Yavsc/src/Model/Booking/BookQuery.cs b/Yavsc/Model/Booking/BookQuery.cs similarity index 100% rename from Yavsc/src/Model/Booking/BookQuery.cs rename to Yavsc/Model/Booking/BookQuery.cs diff --git a/Yavsc/src/Model/Calendar/ICalendarManager.cs b/Yavsc/Model/Calendar/ICalendarManager.cs similarity index 100% rename from Yavsc/src/Model/Calendar/ICalendarManager.cs rename to Yavsc/Model/Calendar/ICalendarManager.cs diff --git a/Yavsc/src/Model/Calendar/IFreeDateSet.cs b/Yavsc/Model/Calendar/IFreeDateSet.cs similarity index 100% rename from Yavsc/src/Model/Calendar/IFreeDateSet.cs rename to Yavsc/Model/Calendar/IFreeDateSet.cs diff --git a/Yavsc/src/Model/Calendar/OpenDay.cs b/Yavsc/Model/Calendar/OpenDay.cs similarity index 100% rename from Yavsc/src/Model/Calendar/OpenDay.cs rename to Yavsc/Model/Calendar/OpenDay.cs diff --git a/Yavsc/src/Model/Calendar/Period.cs b/Yavsc/Model/Calendar/Period.cs similarity index 100% rename from Yavsc/src/Model/Calendar/Period.cs rename to Yavsc/Model/Calendar/Period.cs diff --git a/Yavsc/src/Model/Calendar/Periodicity.cs b/Yavsc/Model/Calendar/Periodicity.cs similarity index 100% rename from Yavsc/src/Model/Calendar/Periodicity.cs rename to Yavsc/Model/Calendar/Periodicity.cs diff --git a/Yavsc/src/Model/Calendar/PositionAndKeyphrase.cs b/Yavsc/Model/Calendar/PositionAndKeyphrase.cs similarity index 100% rename from Yavsc/src/Model/Calendar/PositionAndKeyphrase.cs rename to Yavsc/Model/Calendar/PositionAndKeyphrase.cs diff --git a/Yavsc/src/Model/Calendar/ProvidedEvent.cs b/Yavsc/Model/Calendar/ProvidedEvent.cs similarity index 100% rename from Yavsc/src/Model/Calendar/ProvidedEvent.cs rename to Yavsc/Model/Calendar/ProvidedEvent.cs diff --git a/Yavsc/src/Model/Calendar/Schedule.cs b/Yavsc/Model/Calendar/Schedule.cs similarity index 100% rename from Yavsc/src/Model/Calendar/Schedule.cs rename to Yavsc/Model/Calendar/Schedule.cs diff --git a/Yavsc/src/Model/Calendar/WeekDay.cs b/Yavsc/Model/Calendar/WeekDay.cs similarity index 100% rename from Yavsc/src/Model/Calendar/WeekDay.cs rename to Yavsc/Model/Calendar/WeekDay.cs diff --git a/Yavsc/src/Model/Edition/IDocument.cs b/Yavsc/Model/Edition/IDocument.cs similarity index 100% rename from Yavsc/src/Model/Edition/IDocument.cs rename to Yavsc/Model/Edition/IDocument.cs diff --git a/Yavsc/src/Model/Google/AuthToken.cs b/Yavsc/Model/Google/AuthToken.cs similarity index 100% rename from Yavsc/src/Model/Google/AuthToken.cs rename to Yavsc/Model/Google/AuthToken.cs diff --git a/Yavsc/src/Model/Google/Calendar/CalendarEventList.cs b/Yavsc/Model/Google/Calendar/CalendarEventList.cs similarity index 100% rename from Yavsc/src/Model/Google/Calendar/CalendarEventList.cs rename to Yavsc/Model/Google/Calendar/CalendarEventList.cs diff --git a/Yavsc/src/Model/Google/Calendar/CalendarList.cs b/Yavsc/Model/Google/Calendar/CalendarList.cs similarity index 100% rename from Yavsc/src/Model/Google/Calendar/CalendarList.cs rename to Yavsc/Model/Google/Calendar/CalendarList.cs diff --git a/Yavsc/src/Model/Google/Calendar/CalendarListEntry.cs b/Yavsc/Model/Google/Calendar/CalendarListEntry.cs similarity index 100% rename from Yavsc/src/Model/Google/Calendar/CalendarListEntry.cs rename to Yavsc/Model/Google/Calendar/CalendarListEntry.cs diff --git a/Yavsc/src/Model/Google/GDate.cs b/Yavsc/Model/Google/GDate.cs similarity index 100% rename from Yavsc/src/Model/Google/GDate.cs rename to Yavsc/Model/Google/GDate.cs diff --git a/Yavsc/src/Model/Google/Messaging/GCMRegisterModel.cs b/Yavsc/Model/Google/Messaging/GCMRegisterModel.cs similarity index 100% rename from Yavsc/src/Model/Google/Messaging/GCMRegisterModel.cs rename to Yavsc/Model/Google/Messaging/GCMRegisterModel.cs diff --git a/Yavsc/src/Model/Google/Messaging/MessageWithPayLoad.cs b/Yavsc/Model/Google/Messaging/MessageWithPayLoad.cs similarity index 100% rename from Yavsc/src/Model/Google/Messaging/MessageWithPayLoad.cs rename to Yavsc/Model/Google/Messaging/MessageWithPayLoad.cs diff --git a/Yavsc/src/Model/Google/Messaging/MessageWithPayloadResponse.cs b/Yavsc/Model/Google/Messaging/MessageWithPayloadResponse.cs similarity index 100% rename from Yavsc/src/Model/Google/Messaging/MessageWithPayloadResponse.cs rename to Yavsc/Model/Google/Messaging/MessageWithPayloadResponse.cs diff --git a/Yavsc/src/Model/Google/People/People.cs b/Yavsc/Model/Google/People/People.cs similarity index 100% rename from Yavsc/src/Model/Google/People/People.cs rename to Yavsc/Model/Google/People/People.cs diff --git a/Yavsc/src/Model/Google/Resource.cs b/Yavsc/Model/Google/Resource.cs similarity index 100% rename from Yavsc/src/Model/Google/Resource.cs rename to Yavsc/Model/Google/Resource.cs diff --git a/Yavsc/src/Model/Google/Tracks/Entity.cs b/Yavsc/Model/Google/Tracks/Entity.cs similarity index 100% rename from Yavsc/src/Model/Google/Tracks/Entity.cs rename to Yavsc/Model/Google/Tracks/Entity.cs diff --git a/Yavsc/src/Model/Google/Tracks/EntityQuery.cs b/Yavsc/Model/Google/Tracks/EntityQuery.cs similarity index 100% rename from Yavsc/src/Model/Google/Tracks/EntityQuery.cs rename to Yavsc/Model/Google/Tracks/EntityQuery.cs diff --git a/Yavsc/src/Model/Identity/ApplicationUser.cs b/Yavsc/Model/Identity/ApplicationUser.cs similarity index 100% rename from Yavsc/src/Model/Identity/ApplicationUser.cs rename to Yavsc/Model/Identity/ApplicationUser.cs diff --git a/Yavsc/src/Model/Identity/MobileAppDeclaration.cs b/Yavsc/Model/Identity/MobileAppDeclaration.cs similarity index 100% rename from Yavsc/src/Model/Identity/MobileAppDeclaration.cs rename to Yavsc/Model/Identity/MobileAppDeclaration.cs diff --git a/Yavsc/src/Model/Identity/OAuth2Tokens.cs b/Yavsc/Model/Identity/OAuth2Tokens.cs similarity index 100% rename from Yavsc/src/Model/Identity/OAuth2Tokens.cs rename to Yavsc/Model/Identity/OAuth2Tokens.cs diff --git a/Yavsc/src/Model/Identity/passwrecovery.cs b/Yavsc/Model/Identity/passwrecovery.cs similarity index 100% rename from Yavsc/src/Model/Identity/passwrecovery.cs rename to Yavsc/Model/Identity/passwrecovery.cs diff --git a/Yavsc/src/Model/Market/BaseProduct.cs b/Yavsc/Model/Market/BaseProduct.cs similarity index 100% rename from Yavsc/src/Model/Market/BaseProduct.cs rename to Yavsc/Model/Market/BaseProduct.cs diff --git a/Yavsc/src/Model/Market/Catalog.cs b/Yavsc/Model/Market/Catalog.cs similarity index 100% rename from Yavsc/src/Model/Market/Catalog.cs rename to Yavsc/Model/Market/Catalog.cs diff --git a/Yavsc/src/Model/Market/Product.cs b/Yavsc/Model/Market/Product.cs similarity index 100% rename from Yavsc/src/Model/Market/Product.cs rename to Yavsc/Model/Market/Product.cs diff --git a/Yavsc/src/Model/Market/Service.cs b/Yavsc/Model/Market/Service.cs similarity index 100% rename from Yavsc/src/Model/Market/Service.cs rename to Yavsc/Model/Market/Service.cs diff --git a/Yavsc/src/Model/Messaging/BaseEvent.cs b/Yavsc/Model/Messaging/BaseEvent.cs similarity index 100% rename from Yavsc/src/Model/Messaging/BaseEvent.cs rename to Yavsc/Model/Messaging/BaseEvent.cs diff --git a/Yavsc/src/Model/Messaging/BookQueryEvent.cs b/Yavsc/Model/Messaging/BookQueryEvent.cs similarity index 100% rename from Yavsc/src/Model/Messaging/BookQueryEvent.cs rename to Yavsc/Model/Messaging/BookQueryEvent.cs diff --git a/Yavsc/src/Model/Messaging/CircleEvent.cs b/Yavsc/Model/Messaging/CircleEvent.cs similarity index 100% rename from Yavsc/src/Model/Messaging/CircleEvent.cs rename to Yavsc/Model/Messaging/CircleEvent.cs diff --git a/Yavsc/src/Model/Messaging/Notification.cs b/Yavsc/Model/Messaging/Notification.cs similarity index 100% rename from Yavsc/src/Model/Messaging/Notification.cs rename to Yavsc/Model/Messaging/Notification.cs diff --git a/Yavsc/src/Model/Messaging/YaEvent.cs b/Yavsc/Model/Messaging/YaEvent.cs similarity index 100% rename from Yavsc/src/Model/Messaging/YaEvent.cs rename to Yavsc/Model/Messaging/YaEvent.cs diff --git a/Yavsc/src/Model/Relationship/Circle.cs b/Yavsc/Model/Relationship/Circle.cs similarity index 100% rename from Yavsc/src/Model/Relationship/Circle.cs rename to Yavsc/Model/Relationship/Circle.cs diff --git a/Yavsc/src/Model/Relationship/CircleMember.cs b/Yavsc/Model/Relationship/CircleMember.cs similarity index 100% rename from Yavsc/src/Model/Relationship/CircleMember.cs rename to Yavsc/Model/Relationship/CircleMember.cs diff --git a/Yavsc/src/Model/Relationship/Contact.cs b/Yavsc/Model/Relationship/Contact.cs similarity index 100% rename from Yavsc/src/Model/Relationship/Contact.cs rename to Yavsc/Model/Relationship/Contact.cs diff --git a/Yavsc/src/Model/Relationship/Location.cs b/Yavsc/Model/Relationship/Location.cs similarity index 100% rename from Yavsc/src/Model/Relationship/Location.cs rename to Yavsc/Model/Relationship/Location.cs diff --git a/Yavsc/src/Model/Relationship/Tag.cs b/Yavsc/Model/Relationship/Tag.cs similarity index 100% rename from Yavsc/src/Model/Relationship/Tag.cs rename to Yavsc/Model/Relationship/Tag.cs diff --git a/Yavsc/src/Model/Relationship/Tagged.cs b/Yavsc/Model/Relationship/Tagged.cs similarity index 100% rename from Yavsc/src/Model/Relationship/Tagged.cs rename to Yavsc/Model/Relationship/Tagged.cs diff --git a/Yavsc/src/Model/Workflow/Activity.cs b/Yavsc/Model/Workflow/Activity.cs similarity index 100% rename from Yavsc/src/Model/Workflow/Activity.cs rename to Yavsc/Model/Workflow/Activity.cs diff --git a/Yavsc/src/Model/Workflow/IRequisition.cs b/Yavsc/Model/Workflow/IRequisition.cs similarity index 100% rename from Yavsc/src/Model/Workflow/IRequisition.cs rename to Yavsc/Model/Workflow/IRequisition.cs diff --git a/Yavsc/src/Model/Workflow/PerformerProfile.cs b/Yavsc/Model/Workflow/PerformerProfile.cs similarity index 100% rename from Yavsc/src/Model/Workflow/PerformerProfile.cs rename to Yavsc/Model/Workflow/PerformerProfile.cs diff --git a/Yavsc/src/Model/Workflow/Process/Action.cs b/Yavsc/Model/Workflow/Process/Action.cs similarity index 100% rename from Yavsc/src/Model/Workflow/Process/Action.cs rename to Yavsc/Model/Workflow/Process/Action.cs diff --git a/Yavsc/src/Model/Workflow/Process/Conjonction.cs b/Yavsc/Model/Workflow/Process/Conjonction.cs similarity index 100% rename from Yavsc/src/Model/Workflow/Process/Conjonction.cs rename to Yavsc/Model/Workflow/Process/Conjonction.cs diff --git a/Yavsc/src/Model/Workflow/Process/Disjonction.cs b/Yavsc/Model/Workflow/Process/Disjonction.cs similarity index 100% rename from Yavsc/src/Model/Workflow/Process/Disjonction.cs rename to Yavsc/Model/Workflow/Process/Disjonction.cs diff --git a/Yavsc/src/Model/Workflow/Process/InputValue.cs b/Yavsc/Model/Workflow/Process/InputValue.cs similarity index 100% rename from Yavsc/src/Model/Workflow/Process/InputValue.cs rename to Yavsc/Model/Workflow/Process/InputValue.cs diff --git a/Yavsc/src/Model/Workflow/Process/NamedRequisition.cs b/Yavsc/Model/Workflow/Process/NamedRequisition.cs similarity index 100% rename from Yavsc/src/Model/Workflow/Process/NamedRequisition.cs rename to Yavsc/Model/Workflow/Process/NamedRequisition.cs diff --git a/Yavsc/src/Model/Workflow/Process/Negation.cs b/Yavsc/Model/Workflow/Process/Negation.cs similarity index 100% rename from Yavsc/src/Model/Workflow/Process/Negation.cs rename to Yavsc/Model/Workflow/Process/Negation.cs diff --git a/Yavsc/src/Model/Workflow/Process/Rule.cs b/Yavsc/Model/Workflow/Process/Rule.cs similarity index 100% rename from Yavsc/src/Model/Workflow/Process/Rule.cs rename to Yavsc/Model/Workflow/Process/Rule.cs diff --git a/Yavsc/src/Model/Workflow/Projet.cs b/Yavsc/Model/Workflow/Projet.cs similarity index 100% rename from Yavsc/src/Model/Workflow/Projet.cs rename to Yavsc/Model/Workflow/Projet.cs diff --git a/Yavsc/src/Model/Workflow/Skill.cs b/Yavsc/Model/Workflow/Skill.cs similarity index 100% rename from Yavsc/src/Model/Workflow/Skill.cs rename to Yavsc/Model/Workflow/Skill.cs diff --git a/Yavsc/src/Model/Workflow/UserSkills.cs b/Yavsc/Model/Workflow/UserSkills.cs similarity index 100% rename from Yavsc/src/Model/Workflow/UserSkills.cs rename to Yavsc/Model/Workflow/UserSkills.cs diff --git a/Yavsc/src/Model/Workflow/hr.cs b/Yavsc/Model/Workflow/hr.cs similarity index 100% rename from Yavsc/src/Model/Workflow/hr.cs rename to Yavsc/Model/Workflow/hr.cs diff --git a/Yavsc/src/Model/Workflow/taskdeps.cs b/Yavsc/Model/Workflow/taskdeps.cs similarity index 100% rename from Yavsc/src/Model/Workflow/taskdeps.cs rename to Yavsc/Model/Workflow/taskdeps.cs diff --git a/Yavsc/src/Model/Workflow/tasks.cs b/Yavsc/Model/Workflow/tasks.cs similarity index 100% rename from Yavsc/src/Model/Workflow/tasks.cs rename to Yavsc/Model/Workflow/tasks.cs diff --git a/Yavsc/src/Model/Workflow/wrfiles.cs b/Yavsc/Model/Workflow/wrfiles.cs similarity index 100% rename from Yavsc/src/Model/Workflow/wrfiles.cs rename to Yavsc/Model/Workflow/wrfiles.cs diff --git a/Yavsc/src/Model/societe.com/CompanyInfo.cs b/Yavsc/Model/societe.com/CompanyInfo.cs similarity index 100% rename from Yavsc/src/Model/societe.com/CompanyInfo.cs rename to Yavsc/Model/societe.com/CompanyInfo.cs diff --git a/Yavsc/src/Services/IEmailSender.cs b/Yavsc/Services/IEmailSender.cs similarity index 100% rename from Yavsc/src/Services/IEmailSender.cs rename to Yavsc/Services/IEmailSender.cs diff --git a/Yavsc/src/Services/IGoogleCloudMessageSender.cs b/Yavsc/Services/IGoogleCloudMessageSender.cs similarity index 100% rename from Yavsc/src/Services/IGoogleCloudMessageSender.cs rename to Yavsc/Services/IGoogleCloudMessageSender.cs diff --git a/Yavsc/src/Services/ISmsSender.cs b/Yavsc/Services/ISmsSender.cs similarity index 100% rename from Yavsc/src/Services/ISmsSender.cs rename to Yavsc/Services/ISmsSender.cs diff --git a/Yavsc/src/Services/MessageServices.cs b/Yavsc/Services/MessageServices.cs similarity index 100% rename from Yavsc/src/Services/MessageServices.cs rename to Yavsc/Services/MessageServices.cs diff --git a/Yavsc/src/Services/SIRENCheker.cs b/Yavsc/Services/SIRENCheker.cs similarity index 100% rename from Yavsc/src/Services/SIRENCheker.cs rename to Yavsc/Services/SIRENCheker.cs diff --git a/Yavsc/src/Settings/CompanyInfoSettings.cs b/Yavsc/Settings/CompanyInfoSettings.cs similarity index 100% rename from Yavsc/src/Settings/CompanyInfoSettings.cs rename to Yavsc/Settings/CompanyInfoSettings.cs diff --git a/Yavsc/src/Settings/EmailEntry.cs b/Yavsc/Settings/EmailEntry.cs similarity index 100% rename from Yavsc/src/Settings/EmailEntry.cs rename to Yavsc/Settings/EmailEntry.cs diff --git a/Yavsc/src/Settings/GoogleAuthSettings.cs b/Yavsc/Settings/GoogleAuthSettings.cs similarity index 100% rename from Yavsc/src/Settings/GoogleAuthSettings.cs rename to Yavsc/Settings/GoogleAuthSettings.cs diff --git a/Yavsc/src/Settings/OAuth2AppSettings.cs b/Yavsc/Settings/OAuth2AppSettings.cs similarity index 100% rename from Yavsc/src/Settings/OAuth2AppSettings.cs rename to Yavsc/Settings/OAuth2AppSettings.cs diff --git a/Yavsc/src/Settings/PayPalSettings.cs b/Yavsc/Settings/PayPalSettings.cs similarity index 100% rename from Yavsc/src/Settings/PayPalSettings.cs rename to Yavsc/Settings/PayPalSettings.cs diff --git a/Yavsc/src/Settings/SiteSettings.cs b/Yavsc/Settings/SiteSettings.cs similarity index 100% rename from Yavsc/src/Settings/SiteSettings.cs rename to Yavsc/Settings/SiteSettings.cs diff --git a/Yavsc/src/Settings/SmtpSettings.cs b/Yavsc/Settings/SmtpSettings.cs similarity index 100% rename from Yavsc/src/Settings/SmtpSettings.cs rename to Yavsc/Settings/SmtpSettings.cs diff --git a/Yavsc/src/Settings/ThirdPartyFiles.cs b/Yavsc/Settings/ThirdPartyFiles.cs similarity index 100% rename from Yavsc/src/Settings/ThirdPartyFiles.cs rename to Yavsc/Settings/ThirdPartyFiles.cs diff --git a/Yavsc/src/Settings/TwilioSettings.cs b/Yavsc/Settings/TwilioSettings.cs similarity index 100% rename from Yavsc/src/Settings/TwilioSettings.cs rename to Yavsc/Settings/TwilioSettings.cs diff --git a/Yavsc/Startup/Startup.OAuthHelpers.cs b/Yavsc/Startup/Startup.OAuthHelpers.cs new file mode 100644 index 00000000..e542e692 --- /dev/null +++ b/Yavsc/Startup/Startup.OAuthHelpers.cs @@ -0,0 +1,92 @@ +using System; +using System.Collections.Concurrent; +using System.Linq; +using System.Security.Claims; +using System.Security.Principal; +using System.Threading.Tasks; +using OAuth.AspNet.AuthServer; + +namespace Yavsc +{ + public partial class Startup + { + private readonly ConcurrentDictionary _authenticationCodes = new ConcurrentDictionary(StringComparer.Ordinal); + + private Task ValidateClientRedirectUri(OAuthValidateClientRedirectUriContext context) + { + var app = context.ApplicationStore.FindApplication(context.ClientId); + if (app!=null) + { + context.Validated(app.RedirectUri); + } + return Task.FromResult(0); + } + + private Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context) + { + string clientId,clientSecret; + if (context.TryGetBasicCredentials(out clientId, out clientSecret) || + context.TryGetFormCredentials(out clientId, out clientSecret)) + { + if (ValidateClientCredentials( + new OAuthValidateClientCredentialsContext(clientId,clientSecret,context.ApplicationStore) + )) + { + context.Validated(); + } + } + return Task.FromResult(0); + } + + private bool ValidateClientCredentials(OAuthValidateClientCredentialsContext context) + { + var authapp = context.ApplicationStore.FindApplication(context.ClientId); + if (authapp == null) return false; + if (authapp.Secret == context.ClientSecret) return true; + return false; + } + + private Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context) + { + ClaimsPrincipal principal = new ClaimsPrincipal(new ClaimsIdentity(new GenericIdentity(context.UserName, OAuthDefaults.AuthenticationType), context.Scope.Select(x => new Claim("urn:oauth:scope", x)))); + + context.Validated(principal); + + return Task.FromResult(0); + } + + private Task GrantClientCredetails(OAuthGrantClientCredentialsContext context) + { + ClaimsPrincipal principal = new ClaimsPrincipal(new ClaimsIdentity(new GenericIdentity(context.ClientId, OAuthDefaults.AuthenticationType), context.Scope.Select(x => new Claim("urn:oauth:scope", x)))); + + context.Validated(principal); + + return Task.FromResult(0); + } + + private void CreateAuthenticationCode(AuthenticationTokenCreateContext context) + { + context.SetToken(Guid.NewGuid().ToString("n") + Guid.NewGuid().ToString("n")); + _authenticationCodes[context.Token] = context.SerializeTicket(); + } + + private void ReceiveAuthenticationCode(AuthenticationTokenReceiveContext context) + { + string value; + if (_authenticationCodes.TryRemove(context.Token, out value)) + { + context.DeserializeTicket(value); + } + } + + private void CreateRefreshToken(AuthenticationTokenCreateContext context) + { + context.SetToken(context.SerializeTicket()); + } + + private void ReceiveRefreshToken(AuthenticationTokenReceiveContext context) + { + context.DeserializeTicket(context.Token); + } + } +} diff --git a/Yavsc/src/Startup.cs b/Yavsc/Startup/Startup.cs similarity index 83% rename from Yavsc/src/Startup.cs rename to Yavsc/Startup/Startup.cs index a37d994d..49fe8763 100755 --- a/Yavsc/src/Startup.cs +++ b/Yavsc/Startup/Startup.cs @@ -34,11 +34,8 @@ using Microsoft.Net.Http.Headers; using Yavsc.Auth; using Yavsc.Formatters; using Yavsc.Models; -using Yavsc.Providers; using Yavsc.Services; - - - +using OAuth.AspNet.AuthServer; namespace Yavsc { @@ -67,7 +64,7 @@ namespace Yavsc } } - public class Startup + public partial class Startup { public static string UserFilesDirName { get; private set; } private RsaSecurityKey key; @@ -152,12 +149,12 @@ namespace Yavsc RSAKeyUtils.GetKeyParameters(keyParamsFileInfo.Name) : RSAKeyUtils.GenerateKeyAndSave(keyParamsFileInfo.Name); key = new RsaSecurityKey(keyParams); - + services.Configure(options => { options.SignInScheme = "ServerCookie"; - }); - + }); + services.Configure( to => { @@ -167,7 +164,7 @@ namespace Yavsc new SigningCredentials(key, SecurityAlgorithms.RsaSha256Signature); } ); - + services.Add(ServiceDescriptor.Singleton(typeof(IOptions), typeof(OptionsManager))); services.Add(ServiceDescriptor.Singleton(typeof(IOptions), typeof(OptionsManager))); @@ -192,7 +189,7 @@ namespace Yavsc }); services.AddAuthentication( - op=>op.SignInScheme = "ServerCookie" + op => op.SignInScheme = "ServerCookie" ); // Add framework services. services.AddEntityFramework() @@ -206,9 +203,9 @@ namespace Yavsc option.User.AllowedUserNameCharacters += " "; option.User.RequireUniqueEmail = true; option.Cookies.ApplicationCookie.DataProtectionProvider = - new MonoDataProtectionProvider(Configuration["Site:Title"]); - option.Cookies.ApplicationCookie.CookieName = "Bearer"; - + new MonoDataProtectionProvider(Configuration["Site:Title"]); + option.Cookies.ApplicationCookie.CookieName = "Bearer"; + } ).AddEntityFrameworkStores() .AddTokenProvider>(Constants.EMailFactor) @@ -216,7 +213,7 @@ namespace Yavsc ; // .AddTokenProvider(Constants.SMSFactor) // - + services.AddCors( /* options => @@ -239,14 +236,14 @@ namespace Yavsc services.AddAuthorization(options => { - + options.AddPolicy("AdministratorOnly", policy => { policy.RequireClaim("http://schemas.microsoft.com/ws/2008/06/identity/claims/role", Constants.AdminGroupName); }); options.AddPolicy("FrontOffice", policy => policy.RequireRole(Constants.FrontOfficeGroupName)); - options.AddPolicy("Bearer",new AuthorizationPolicyBuilder() + options.AddPolicy("Bearer", new AuthorizationPolicyBuilder() .AddAuthenticationSchemes("ServerCookie") .RequireAuthenticatedUser().Build()); // options.AddPolicy("EmployeeId", policy => policy.RequireClaim("EmployeeId", "123", "456")); @@ -261,7 +258,7 @@ namespace Yavsc services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); - + services.AddMvc(config => { var policy = new AuthorizationPolicyBuilder() @@ -290,6 +287,8 @@ namespace Yavsc services.AddTransient, Microsoft.AspNet.Authentication.SecureDataFormat>(); services.AddTransient, TicketDataFormat>(); + services.AddTransient(); + // Add application services. services.AddTransient(); services.AddTransient(); @@ -299,15 +298,13 @@ namespace Yavsc { options.ResourcesPath = "Resources"; }); - - } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env, - IOptions siteSettings, + IOptions siteSettings, IOptions localizationOptions, - IOptions oauth2SettingsContainer, + IOptions oauth2SettingsContainer, ILoggerFactory loggerFactory) { Startup.UserFilesDirName = siteSettings.Value.UserFiles.DirName; @@ -391,7 +388,7 @@ namespace Yavsc options.AuthenticationDescriptions.Clear(); options.AutomaticAuthentication = true; }); - + app.UseFileServer(new FileServerOptions() { FileProvider = new PhysicalFileProvider( @@ -406,59 +403,98 @@ namespace Yavsc EnableDirectoryBrowsing = false }); app.UseStaticFiles().UseWebSockets(); - + app.UseIdentity(); - app.UseOpenIdConnectServer(options => - { - options.Provider = new AuthorizationProvider(loggerFactory, - new UserTokenProvider()); - - // Register the certificate used to sign the JWT tokens. - // options.SigningCredentials.AddCertificate( - // assembly: typeof(Startup).GetTypeInfo().Assembly, - // resource: "Mvc.Server.Certificate.pfx", - // password: "Owin.Security.OpenIdConnect.Server"); - - // options.SigningCredentials.AddKey(key); - // Note: see AuthorizationController.cs for more - // information concerning ApplicationCanDisplayErrors. - options.ApplicationCanDisplayErrors = true; - options.AllowInsecureHttp = true; - options.AutomaticChallenge = true; - // options.AutomaticAuthenticate=true; - - - options.AuthorizationEndpointPath = new PathString("/connect/authorize"); - options.TokenEndpointPath = new PathString("/connect/authorize/accept"); - options.UseSlidingExpiration = true; - options.AllowInsecureHttp = true; - options.AuthenticationScheme = "oidc-server"; // was = OpenIdConnectDefaults.AuthenticationScheme || "oidc"; - options.LogoutEndpointPath = new PathString("/connect/logout"); - - // options.ValidationEndpointPath = new PathString("/connect/introspect"); - }); /**/ - app.UseCookieAuthentication(options => + + + /* app.UseOpenIdConnectServer(options => { - options.AutomaticAuthenticate = true; + options.Provider = new AuthorizationProvider(loggerFactory, + new UserTokenProvider()); + + // Register the certificate used to sign the JWT tokens. + // options.SigningCredentials.AddCertificate( + // assembly: typeof(Startup).GetTypeInfo().Assembly, + // resource: "Mvc.Server.Certificate.pfx", + // password: "Owin.Security.OpenIdConnect.Server"); + + // options.SigningCredentials.AddKey(key); + // Note: see AuthorizationController.cs for more + // information concerning ApplicationCanDisplayErrors. + options.ApplicationCanDisplayErrors = true; + options.AllowInsecureHttp = true; options.AutomaticChallenge = true; - options.AuthenticationScheme = "ServerCookie"; - options.ExpireTimeSpan = TimeSpan.FromMinutes(5); + // options.AutomaticAuthenticate=true; + + + options.AuthorizationEndpointPath = new PathString("/connect/authorize"); + options.TokenEndpointPath = new PathString("/connect/authorize/accept"); + options.UseSlidingExpiration = true; + options.AllowInsecureHttp = true; + options.AuthenticationScheme = "oidc-server"; // was = OpenIdConnectDefaults.AuthenticationScheme || "oidc"; + options.LogoutEndpointPath = new PathString("/connect/logout"); + + // options.ValidationEndpointPath = new PathString("/connect/introspect"); + }); */ + + app.UseCookieAuthentication(options => + { + options.AutomaticAuthenticate = true; + options.AutomaticChallenge = true; + options.AuthenticationScheme = "ServerCookie"; + options.ExpireTimeSpan = TimeSpan.FromMinutes(5); options.LoginPath = new PathString("/signin"); options.LogoutPath = new PathString("/signout"); options.CookieName = "Bearer"; - }); + }); - app.UseMiddleware(googleOptions); + app.UseMiddleware(googleOptions); - // Facebook - app.UseFacebookAuthentication(options => - { - options.AppId = Configuration["Authentication:Facebook:AppId"]; - options.AppSecret = Configuration["Authentication:Facebook:AppSecret"]; - options.Scope.Add("email"); - options.UserInformationEndpoint = "https://graph.facebook.com/v2.5/me?fields=id,name,email,first_name,last_name"; - }); + // Facebook + app.UseFacebookAuthentication(options => + { + options.AppId = Configuration["Authentication:Facebook:AppId"]; + options.AppSecret = Configuration["Authentication:Facebook:AppSecret"]; + options.Scope.Add("email"); + options.UserInformationEndpoint = "https://graph.facebook.com/v2.5/me?fields=id,name,email,first_name,last_name"; + }); + + app.UseOAuthAuthorizationServer( + options => + { + options.AuthorizeEndpointPath = new PathString("/signin"); + options.TokenEndpointPath = new PathString("/token"); + options.ApplicationCanDisplayErrors = true; + +#if DEBUG + options.AllowInsecureHttp = true; +#endif + + options.Provider = new OAuthAuthorizationServerProvider + { + OnValidateClientRedirectUri = ValidateClientRedirectUri, + OnValidateClientAuthentication = ValidateClientAuthentication, + OnGrantResourceOwnerCredentials = GrantResourceOwnerCredentials, + OnGrantClientCredentials = GrantClientCredetails + }; + + options.AuthorizationCodeProvider = new AuthenticationTokenProvider + { + OnCreate = CreateAuthenticationCode, + OnReceive = ReceiveAuthenticationCode, + }; + + options.RefreshTokenProvider = new AuthenticationTokenProvider + { + OnCreate = CreateRefreshToken, + OnReceive = ReceiveRefreshToken, + }; + + options.AutomaticAuthenticate = false; + } + ); + app.UseRequestLocalization(localizationOptions.Value, (RequestCulture)new RequestCulture((string)"fr")); /* Generic OAuth (here GitHub): options.Notifications = new OAuthAuthenticationNotifications diff --git a/Yavsc/src/ViewModels/Account/ChangePasswordBindingModel.cs b/Yavsc/ViewModels/Account/ChangePasswordBindingModel.cs similarity index 100% rename from Yavsc/src/ViewModels/Account/ChangePasswordBindingModel.cs rename to Yavsc/ViewModels/Account/ChangePasswordBindingModel.cs diff --git a/Yavsc/src/ViewModels/Account/ExternalLoginConfirmationViewModel.cs b/Yavsc/ViewModels/Account/ExternalLoginConfirmationViewModel.cs similarity index 100% rename from Yavsc/src/ViewModels/Account/ExternalLoginConfirmationViewModel.cs rename to Yavsc/ViewModels/Account/ExternalLoginConfirmationViewModel.cs diff --git a/Yavsc/src/ViewModels/Account/ForgotPasswordViewModel.cs b/Yavsc/ViewModels/Account/ForgotPasswordViewModel.cs similarity index 100% rename from Yavsc/src/ViewModels/Account/ForgotPasswordViewModel.cs rename to Yavsc/ViewModels/Account/ForgotPasswordViewModel.cs diff --git a/Yavsc/src/ViewModels/Account/LoginViewModel.cs b/Yavsc/ViewModels/Account/LoginViewModel.cs similarity index 100% rename from Yavsc/src/ViewModels/Account/LoginViewModel.cs rename to Yavsc/ViewModels/Account/LoginViewModel.cs diff --git a/Yavsc/src/ViewModels/Account/RegisterViewModel.cs b/Yavsc/ViewModels/Account/RegisterViewModel.cs similarity index 100% rename from Yavsc/src/ViewModels/Account/RegisterViewModel.cs rename to Yavsc/ViewModels/Account/RegisterViewModel.cs diff --git a/Yavsc/src/ViewModels/Account/ResetPasswordViewModel.cs b/Yavsc/ViewModels/Account/ResetPasswordViewModel.cs similarity index 100% rename from Yavsc/src/ViewModels/Account/ResetPasswordViewModel.cs rename to Yavsc/ViewModels/Account/ResetPasswordViewModel.cs diff --git a/Yavsc/src/ViewModels/Account/SendCodeViewModel.cs b/Yavsc/ViewModels/Account/SendCodeViewModel.cs similarity index 100% rename from Yavsc/src/ViewModels/Account/SendCodeViewModel.cs rename to Yavsc/ViewModels/Account/SendCodeViewModel.cs diff --git a/Yavsc/src/ViewModels/Account/UnregisterViewModel.cs b/Yavsc/ViewModels/Account/UnregisterViewModel.cs similarity index 100% rename from Yavsc/src/ViewModels/Account/UnregisterViewModel.cs rename to Yavsc/ViewModels/Account/UnregisterViewModel.cs diff --git a/Yavsc/src/ViewModels/Account/VerifyCodeViewModel.cs b/Yavsc/ViewModels/Account/VerifyCodeViewModel.cs similarity index 100% rename from Yavsc/src/ViewModels/Account/VerifyCodeViewModel.cs rename to Yavsc/ViewModels/Account/VerifyCodeViewModel.cs diff --git a/Yavsc/src/ViewModels/Auth/AuthorisationHandlers.cs b/Yavsc/ViewModels/Auth/AuthorisationHandlers.cs similarity index 100% rename from Yavsc/src/ViewModels/Auth/AuthorisationHandlers.cs rename to Yavsc/ViewModels/Auth/AuthorisationHandlers.cs diff --git a/Yavsc/src/ViewModels/Auth/AuthorisationView.cs b/Yavsc/ViewModels/Auth/AuthorisationView.cs similarity index 100% rename from Yavsc/src/ViewModels/Auth/AuthorisationView.cs rename to Yavsc/ViewModels/Auth/AuthorisationView.cs diff --git a/Yavsc/src/ViewModels/Auth/ClaimTypes.cs b/Yavsc/ViewModels/Auth/ClaimTypes.cs similarity index 100% rename from Yavsc/src/ViewModels/Auth/ClaimTypes.cs rename to Yavsc/ViewModels/Auth/ClaimTypes.cs diff --git a/Yavsc/src/ViewModels/Calendar/SetGoogleCalendarViewModel.cs b/Yavsc/ViewModels/Calendar/SetGoogleCalendarViewModel.cs similarity index 100% rename from Yavsc/src/ViewModels/Calendar/SetGoogleCalendarViewModel.cs rename to Yavsc/ViewModels/Calendar/SetGoogleCalendarViewModel.cs diff --git a/Yavsc/src/ViewModels/Calendar/UpcomingEventsViewModel.cs b/Yavsc/ViewModels/Calendar/UpcomingEventsViewModel.cs similarity index 100% rename from Yavsc/src/ViewModels/Calendar/UpcomingEventsViewModel.cs rename to Yavsc/ViewModels/Calendar/UpcomingEventsViewModel.cs diff --git a/Yavsc/src/ViewModels/Manage/AddPhoneNumberViewModel.cs b/Yavsc/ViewModels/Manage/AddPhoneNumberViewModel.cs similarity index 100% rename from Yavsc/src/ViewModels/Manage/AddPhoneNumberViewModel.cs rename to Yavsc/ViewModels/Manage/AddPhoneNumberViewModel.cs diff --git a/Yavsc/src/ViewModels/Manage/ChangePasswordViewModel.cs b/Yavsc/ViewModels/Manage/ChangePasswordViewModel.cs similarity index 100% rename from Yavsc/src/ViewModels/Manage/ChangePasswordViewModel.cs rename to Yavsc/ViewModels/Manage/ChangePasswordViewModel.cs diff --git a/Yavsc/src/ViewModels/Manage/ChangeUserNameViewModel.cs b/Yavsc/ViewModels/Manage/ChangeUserNameViewModel.cs similarity index 100% rename from Yavsc/src/ViewModels/Manage/ChangeUserNameViewModel.cs rename to Yavsc/ViewModels/Manage/ChangeUserNameViewModel.cs diff --git a/Yavsc/src/ViewModels/Manage/ConfigureTwoFactorViewModel.cs b/Yavsc/ViewModels/Manage/ConfigureTwoFactorViewModel.cs similarity index 100% rename from Yavsc/src/ViewModels/Manage/ConfigureTwoFactorViewModel.cs rename to Yavsc/ViewModels/Manage/ConfigureTwoFactorViewModel.cs diff --git a/Yavsc/src/ViewModels/Manage/FactorViewModel.cs b/Yavsc/ViewModels/Manage/FactorViewModel.cs similarity index 100% rename from Yavsc/src/ViewModels/Manage/FactorViewModel.cs rename to Yavsc/ViewModels/Manage/FactorViewModel.cs diff --git a/Yavsc/src/ViewModels/Manage/IndexViewModel.cs b/Yavsc/ViewModels/Manage/IndexViewModel.cs similarity index 100% rename from Yavsc/src/ViewModels/Manage/IndexViewModel.cs rename to Yavsc/ViewModels/Manage/IndexViewModel.cs diff --git a/Yavsc/src/ViewModels/Manage/ManageLoginsViewModel.cs b/Yavsc/ViewModels/Manage/ManageLoginsViewModel.cs similarity index 100% rename from Yavsc/src/ViewModels/Manage/ManageLoginsViewModel.cs rename to Yavsc/ViewModels/Manage/ManageLoginsViewModel.cs diff --git a/Yavsc/src/ViewModels/Manage/RemoveLoginViewModel.cs b/Yavsc/ViewModels/Manage/RemoveLoginViewModel.cs similarity index 100% rename from Yavsc/src/ViewModels/Manage/RemoveLoginViewModel.cs rename to Yavsc/ViewModels/Manage/RemoveLoginViewModel.cs diff --git a/Yavsc/src/ViewModels/Manage/SetPasswordViewModel.cs b/Yavsc/ViewModels/Manage/SetPasswordViewModel.cs similarity index 100% rename from Yavsc/src/ViewModels/Manage/SetPasswordViewModel.cs rename to Yavsc/ViewModels/Manage/SetPasswordViewModel.cs diff --git a/Yavsc/src/ViewModels/Manage/VerifyPhoneNumberViewModel.cs b/Yavsc/ViewModels/Manage/VerifyPhoneNumberViewModel.cs similarity index 100% rename from Yavsc/src/ViewModels/Manage/VerifyPhoneNumberViewModel.cs rename to Yavsc/ViewModels/Manage/VerifyPhoneNumberViewModel.cs diff --git a/Yavsc/src/ViewModels/UserFiles/BlogFilesPost.cs b/Yavsc/ViewModels/UserFiles/BlogFilesPost.cs similarity index 100% rename from Yavsc/src/ViewModels/UserFiles/BlogFilesPost.cs rename to Yavsc/ViewModels/UserFiles/BlogFilesPost.cs diff --git a/Yavsc/src/ViewModels/UserFiles/FileInfo.cs b/Yavsc/ViewModels/UserFiles/FileInfo.cs similarity index 100% rename from Yavsc/src/ViewModels/UserFiles/FileInfo.cs rename to Yavsc/ViewModels/UserFiles/FileInfo.cs diff --git a/Yavsc/project.json b/Yavsc/project.json index b6089572..3e636c6a 100755 --- a/Yavsc/project.json +++ b/Yavsc/project.json @@ -45,75 +45,71 @@ "defaultNamespace": "Yavsc" }, "dependencies": { + "EntityFramework.Commands": "7.0.0-rc1-*", "EntityFramework.Core": "7.0.0-rc1-*", + "EntityFramework.MicrosoftSqlServer": "7.0.0-rc1-*", "EntityFramework.Relational": "7.0.0-rc1-*", - "EntityFramework.Commands": "7.0.0-rc1-*", "EntityFramework.Sqlite": "7.0.0-rc1-*", - "EntityFramework.MicrosoftSqlServer": "7.0.0-rc1-*", "EntityFramework7.Npgsql": "3.1.0-*", "EntityFramework7.Npgsql.Design": "3.1.0-*", + "Google.Apis.Core": "1.11.1", + "Google.Apis": "1.11.1", + "MailKit": "1.3.0-beta7", + "MarkdownDeep-av.NET": "1.5.2", "Microsoft.AspNet.Authentication.Cookies": "1.0.0-rc1-*", + "Microsoft.AspNet.Authentication.Facebook": "1.0.0-rc1-final", + "Microsoft.AspNet.Authentication.Twitter": "1.0.0-rc1-final", + "Microsoft.AspNet.Authorization": "1.0.0-rc1-final", "Microsoft.AspNet.Diagnostics.Entity": "7.0.0-rc1-*", + "Microsoft.AspNet.Http.Abstractions": "1.0.0-rc1-final", "Microsoft.AspNet.Identity.EntityFramework": "3.0.0-rc1-*", "Microsoft.AspNet.IISPlatformHandler": "1.0.0-rc1-*", + "Microsoft.AspNet.Localization": "1.0.0-rc1-final", "Microsoft.AspNet.Mvc": "6.0.0-rc1-*", "Microsoft.AspNet.Mvc.TagHelpers": "6.0.0-rc1-*", + "Microsoft.AspNet.Owin": "1.0.0-rc1-final", "Microsoft.AspNet.Server.Kestrel": "1.0.0-rc1-final", + "Microsoft.AspNet.SignalR.Owin": "1.2.2", + "Microsoft.AspNet.SignalR.Core": "2.2.0", + "Microsoft.AspNet.Server.WebListener": "1.0.0-rc1-final", "Microsoft.AspNet.StaticFiles": "1.0.0-rc1-*", + "Microsoft.AspNet.SignalR.JS": "2.2.0", "Microsoft.AspNet.Tooling.Razor": "1.0.0-rc1-*", + "Microsoft.AspNet.WebSockets.Server": "1.0.0-rc1-final", + "Microsoft.AspNet.Authentication.OpenIdConnect": "1.0.0-rc1-final", + "Microsoft.Extensions.Configuration.Abstractions": "1.0.0-rc1-final", "Microsoft.Extensions.Configuration.FileProviderExtensions": "1.0.0-rc1-*", "Microsoft.Extensions.Configuration.Json": "1.0.0-rc1-*", - "Microsoft.Extensions.Configuration.Abstractions": "1.0.0-rc1-final", "Microsoft.Extensions.Configuration.UserSecrets": "1.0.0-rc1-*", "Microsoft.Extensions.Logging": "1.0.0-rc1-final", "Microsoft.Extensions.Logging.Console": "1.0.0-rc1-final", "Microsoft.Extensions.Logging.Debug": "1.0.0-rc1-final", - "Microsoft.Framework.DependencyInjection": "1.0.0-beta8", "Microsoft.Extensions.DependencyInjection.Abstractions": "1.0.0-rc1-final", - "Microsoft.AspNet.Authentication.Facebook": "1.0.0-rc1-final", - "Microsoft.AspNet.Authentication.Twitter": "1.0.0-rc1-final", + "Microsoft.Extensions.Globalization.CultureInfoCache": "1.0.0-rc1-final", "Microsoft.Extensions.Localization": "1.0.0-rc1-final", "Microsoft.Extensions.Localization.Abstractions": "1.0.0-rc1-final", - "Microsoft.Extensions.Globalization.CultureInfoCache": "1.0.0-rc1-final", - "Microsoft.AspNet.Localization": "1.0.0-rc1-final", "Microsoft.Framework.ConfigurationModel.Json": "1.0.0-beta4", - "MarkdownDeep-av.NET": "1.5.2", + "Microsoft.Framework.DependencyInjection": "1.0.0-beta8", + "Microsoft.Extensions.CodeGeneration": "1.0.0-rc1-final", "Microsoft.Extensions.PlatformAbstractions": "1.0.0-rc1-final", "Microsoft.Extensions.CodeGenerators.Mvc": "1.0.0-rc1-final", "Microsoft.AspNet.Session": "1.0.0-rc1-final", "Microsoft.NETCore.Platforms": "1.0.1-beta-23516", - "Microsoft.AspNet.SignalR.JS": "2.2.0", - "Microsoft.AspNet.WebSockets.Server": "1.0.0-rc1-final", - "Microsoft.AspNet.Http.Abstractions": "1.0.0-rc1-final", - "Microsoft.AspNet.SignalR.Owin": "1.2.2", - "Microsoft.AspNet.Owin": "1.0.0-rc1-final", - "Microsoft.AspNet.SignalR.Core": "2.2.0", - "Microsoft.AspNet.Server.WebListener": "1.0.0-rc1-final", - "Microsoft.AspNetCore.Authentication.OpenIdConnect": "0.0.1-alpha", - "Microsoft.AspNetCore.Authentication.Cookies": "0.0.1-alpha", - "Microsoft.AspNet.Authentication.OpenIdConnect": "1.0.0-rc1-final", - "MailKit": "1.3.0-beta7", "Microsoft.Framework.Configuration.Abstractions": "1.0.0-beta8", "Microsoft.Framework.Configuration.Json": "1.0.0-beta8", "Microsoft.Framework.DependencyInjection.Abstractions": "1.0.0-beta8", "Microsoft.Framework.Configuration.Binder": "1.0.0-beta8", "Microsoft.AspNet.Web.Optimization": "1.1.3", - "PayPalCoreSDK": "1.7.1", "Microsoft.Extensions.WebEncoders.Core": "1.0.0-rc1-final", "Microsoft.AspNetCore.Authentication.OAuth": "0.0.1-alpha", "Microsoft.Extensions.Options": "0.0.1-alpha", "Microsoft.Extensions.WebEncoders": "1.0.0-rc1-final", - "Google.Apis.Core": "1.11.1", - "Google.Apis": "1.11.1", - "PayPalButtonManagerSDK": "2.10.109", "Microsoft.AspNet.DataProtection": "1.0.0-rc1-final", "Microsoft.AspNet.DataProtection.SystemWeb": "1.0.0-rc1-final", "Microsoft.AspNet.Authentication.JwtBearer": "1.0.0-rc1-final", - "System.IdentityModel.Tokens": "5.0.0-rc1-211161024", - "System.IdentityModel.Tokens.Jwt": "5.0.0-rc1-211161024", - "Microsoft.AspNet.Authorization": "1.0.0-rc1-final", - "AspNet.Security.OpenIdConnect.Server": "1.0.0-beta4" + "PayPalCoreSDK": "1.7.1", + "PayPalButtonManagerSDK": "2.10.109" }, "commands": { "web": "Microsoft.AspNet.Server.Kestrel --server.urls http://*:5000", @@ -149,4 +145,4 @@ "prepublish": "gulp min", "postpublish": "./postPublish.sh" } -} +} \ No newline at end of file diff --git a/Yavsc/project.json.new b/Yavsc/project.json.new deleted file mode 100755 index b6089572..00000000 --- a/Yavsc/project.json.new +++ /dev/null @@ -1,152 +0,0 @@ -{ - "version": "1.0.0-*", - "authors": [ - "pazof" - ], - "tags": [ - "" - ], - "projectUrl": "http://yavsc.pschneider.fr", - "licenseUrl": "", - "userSecretsId": "aspnet5-YavscWeb-a0dadd21-2ced-43d3-96f9-7e504345102f", - "compilationOptions": { - "emitEntryPoint": true - }, - "compile": [ - "*.cs" - ], - "resource": [ - "Resources/**/*.resx" - ], - "configurations": { - "Debug": { - "compilationOptions": { - "emitEntryPoint": true, - "define": [ - "DEBUG", - "TRACE" - ], - "optimize": false, - "debugType": "full" - } - }, - "Release": { - "compilationOptions": { - "define": [ - "RELEASE", - "TRACE" - ], - "optimize": true - } - } - }, - "webroot": "wwwroot", - "tooling": { - "defaultNamespace": "Yavsc" - }, - "dependencies": { - "EntityFramework.Core": "7.0.0-rc1-*", - "EntityFramework.Relational": "7.0.0-rc1-*", - "EntityFramework.Commands": "7.0.0-rc1-*", - "EntityFramework.Sqlite": "7.0.0-rc1-*", - "EntityFramework.MicrosoftSqlServer": "7.0.0-rc1-*", - "EntityFramework7.Npgsql": "3.1.0-*", - "EntityFramework7.Npgsql.Design": "3.1.0-*", - "Microsoft.AspNet.Authentication.Cookies": "1.0.0-rc1-*", - "Microsoft.AspNet.Diagnostics.Entity": "7.0.0-rc1-*", - "Microsoft.AspNet.Identity.EntityFramework": "3.0.0-rc1-*", - "Microsoft.AspNet.IISPlatformHandler": "1.0.0-rc1-*", - "Microsoft.AspNet.Mvc": "6.0.0-rc1-*", - "Microsoft.AspNet.Mvc.TagHelpers": "6.0.0-rc1-*", - "Microsoft.AspNet.Server.Kestrel": "1.0.0-rc1-final", - "Microsoft.AspNet.StaticFiles": "1.0.0-rc1-*", - "Microsoft.AspNet.Tooling.Razor": "1.0.0-rc1-*", - "Microsoft.Extensions.Configuration.FileProviderExtensions": "1.0.0-rc1-*", - "Microsoft.Extensions.Configuration.Json": "1.0.0-rc1-*", - "Microsoft.Extensions.Configuration.Abstractions": "1.0.0-rc1-final", - "Microsoft.Extensions.Configuration.UserSecrets": "1.0.0-rc1-*", - "Microsoft.Extensions.Logging": "1.0.0-rc1-final", - "Microsoft.Extensions.Logging.Console": "1.0.0-rc1-final", - "Microsoft.Extensions.Logging.Debug": "1.0.0-rc1-final", - "Microsoft.Framework.DependencyInjection": "1.0.0-beta8", - "Microsoft.Extensions.DependencyInjection.Abstractions": "1.0.0-rc1-final", - "Microsoft.AspNet.Authentication.Facebook": "1.0.0-rc1-final", - "Microsoft.AspNet.Authentication.Twitter": "1.0.0-rc1-final", - "Microsoft.Extensions.Localization": "1.0.0-rc1-final", - "Microsoft.Extensions.Localization.Abstractions": "1.0.0-rc1-final", - "Microsoft.Extensions.Globalization.CultureInfoCache": "1.0.0-rc1-final", - "Microsoft.AspNet.Localization": "1.0.0-rc1-final", - "Microsoft.Framework.ConfigurationModel.Json": "1.0.0-beta4", - "MarkdownDeep-av.NET": "1.5.2", - "Microsoft.Extensions.CodeGeneration": "1.0.0-rc1-final", - "Microsoft.Extensions.PlatformAbstractions": "1.0.0-rc1-final", - "Microsoft.Extensions.CodeGenerators.Mvc": "1.0.0-rc1-final", - "Microsoft.AspNet.Session": "1.0.0-rc1-final", - "Microsoft.NETCore.Platforms": "1.0.1-beta-23516", - "Microsoft.AspNet.SignalR.JS": "2.2.0", - "Microsoft.AspNet.WebSockets.Server": "1.0.0-rc1-final", - "Microsoft.AspNet.Http.Abstractions": "1.0.0-rc1-final", - "Microsoft.AspNet.SignalR.Owin": "1.2.2", - "Microsoft.AspNet.Owin": "1.0.0-rc1-final", - "Microsoft.AspNet.SignalR.Core": "2.2.0", - "Microsoft.AspNet.Server.WebListener": "1.0.0-rc1-final", - "Microsoft.AspNetCore.Authentication.OpenIdConnect": "0.0.1-alpha", - "Microsoft.AspNetCore.Authentication.Cookies": "0.0.1-alpha", - "Microsoft.AspNet.Authentication.OpenIdConnect": "1.0.0-rc1-final", - "MailKit": "1.3.0-beta7", - "Microsoft.Framework.Configuration.Abstractions": "1.0.0-beta8", - "Microsoft.Framework.Configuration.Json": "1.0.0-beta8", - "Microsoft.Framework.DependencyInjection.Abstractions": "1.0.0-beta8", - "Microsoft.Framework.Configuration.Binder": "1.0.0-beta8", - "Microsoft.AspNet.Web.Optimization": "1.1.3", - "PayPalCoreSDK": "1.7.1", - "Microsoft.Extensions.WebEncoders.Core": "1.0.0-rc1-final", - "Microsoft.AspNetCore.Authentication.OAuth": "0.0.1-alpha", - "Microsoft.Extensions.Options": "0.0.1-alpha", - "Microsoft.Extensions.WebEncoders": "1.0.0-rc1-final", - "Google.Apis.Core": "1.11.1", - "Google.Apis": "1.11.1", - "PayPalButtonManagerSDK": "2.10.109", - "Microsoft.AspNet.DataProtection": "1.0.0-rc1-final", - "Microsoft.AspNet.DataProtection.SystemWeb": "1.0.0-rc1-final", - "Microsoft.AspNet.Authentication.JwtBearer": "1.0.0-rc1-final", - "System.IdentityModel.Tokens": "5.0.0-rc1-211161024", - "System.IdentityModel.Tokens.Jwt": "5.0.0-rc1-211161024", - "Microsoft.AspNet.Authorization": "1.0.0-rc1-final", - "AspNet.Security.OpenIdConnect.Server": "1.0.0-beta4" - }, - "commands": { - "web": "Microsoft.AspNet.Server.Kestrel --server.urls http://*:5000", - "lua": "Microsoft.AspNet.Hosting --server Microsoft.AspNet.Server.Kestrel --server.urls http://*:85", - "kestrel": "Microsoft.AspNet.Hosting --server Microsoft.AspNet.Server.Kestrel --server.urls http://*:5000", - "booking": "Microsoft.AspNet.Hosting --server Microsoft.AspNet.Server.Kestrel --server.urls http://*:87", - "yavsc": "Microsoft.AspNet.Hosting --server Microsoft.AspNet.Server.Kestrel --server.urls http://*:86", - "yavscpre": "Microsoft.AspNet.Hosting --server Microsoft.AspNet.Server.Kestrel --server.urls http://*:84", - "ef": "EntityFramework.Commands", - "gen": "Microsoft.Extensions.CodeGeneration" - }, - "frameworks": { - "dnx451": {} - }, - "exclude": [ - "wwwroot", - "node_modules", - "bower_components", - "contrib" - ], - "publishExclude": [ - "**.user", - "**.vspscc", - "contrib/**/*.*" - ], - "scripts": { - "prebuild": "echo before building", - "postbuild": "echo after building", - "prepack": "gulp min", - "postpack": "echo after packing", - "prerestore": "echo before restoring packages", - "postrestore": "echo after restoring packages", - "prepublish": "gulp min", - "postpublish": "./postPublish.sh" - } -} diff --git a/Yavsc/project.lock.json b/Yavsc/project.lock.json index 460a8357..9a3cd2d9 100644 --- a/Yavsc/project.lock.json +++ b/Yavsc/project.lock.json @@ -12,48 +12,6 @@ "lib/Antlr3.Runtime.dll": {} } }, - "AspNet.Security.OpenIdConnect.Extensions/1.0.0-beta4": { - "type": "package", - "dependencies": { - "Microsoft.AspNet.Authentication": "1.0.0-rc1-final", - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "2.0.0-rc1-211161024" - }, - "frameworkAssemblies": [ - "Microsoft.CSharp", - "mscorlib", - "System", - "System.Core" - ], - "compile": { - "lib/dnx451/AspNet.Security.OpenIdConnect.Extensions.dll": {} - }, - "runtime": { - "lib/dnx451/AspNet.Security.OpenIdConnect.Extensions.dll": {} - } - }, - "AspNet.Security.OpenIdConnect.Server/1.0.0-beta4": { - "type": "package", - "dependencies": { - "AspNet.Security.OpenIdConnect.Extensions": "1.0.0-beta4", - "Microsoft.AspNet.Authentication": "1.0.0-rc1-final", - "Microsoft.AspNet.Hosting.Abstractions": "1.0.0-rc1-final", - "Microsoft.Extensions.Caching.Abstractions": "1.0.0-rc1-final", - "Microsoft.Extensions.Logging.Abstractions": "1.0.0-rc1-final", - "Newtonsoft.Json": "7.0.1" - }, - "frameworkAssemblies": [ - "Microsoft.CSharp", - "mscorlib", - "System", - "System.Core" - ], - "compile": { - "lib/dnx451/AspNet.Security.OpenIdConnect.Server.dll": {} - }, - "runtime": { - "lib/dnx451/AspNet.Security.OpenIdConnect.Server.dll": {} - } - }, "EntityFramework.Commands/7.0.0-rc1-final": { "type": "package", "dependencies": { @@ -260,12 +218,12 @@ "Zlib.Portable.Signed": "1.11.0" }, "compile": { - "lib/net45/Google.Apis.dll": {}, - "lib/net45/Google.Apis.PlatformServices.dll": {} + "lib/net45/Google.Apis.PlatformServices.dll": {}, + "lib/net45/Google.Apis.dll": {} }, "runtime": { - "lib/net45/Google.Apis.dll": {}, - "lib/net45/Google.Apis.PlatformServices.dll": {} + "lib/net45/Google.Apis.PlatformServices.dll": {}, + "lib/net45/Google.Apis.dll": {} } }, "Google.Apis.Core/1.11.1": { @@ -1569,15 +1527,9 @@ "lib/net451/Microsoft.AspNet.WebUtilities.dll": {} } }, - "Microsoft.AspNetCore.Authentication.Cookies/0.0.1-alpha": { - "type": "package" - }, "Microsoft.AspNetCore.Authentication.OAuth/0.0.1-alpha": { "type": "package" }, - "Microsoft.AspNetCore.Authentication.OpenIdConnect/0.0.1-alpha": { - "type": "package" - }, "Microsoft.CodeAnalysis.Analyzers/1.0.0": { "type": "package", "frameworkAssemblies": [ @@ -2975,48 +2927,6 @@ "lib/Antlr3.Runtime.dll": {} } }, - "AspNet.Security.OpenIdConnect.Extensions/1.0.0-beta4": { - "type": "package", - "dependencies": { - "Microsoft.AspNet.Authentication": "1.0.0-rc1-final", - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "2.0.0-rc1-211161024" - }, - "frameworkAssemblies": [ - "Microsoft.CSharp", - "mscorlib", - "System", - "System.Core" - ], - "compile": { - "lib/dnx451/AspNet.Security.OpenIdConnect.Extensions.dll": {} - }, - "runtime": { - "lib/dnx451/AspNet.Security.OpenIdConnect.Extensions.dll": {} - } - }, - "AspNet.Security.OpenIdConnect.Server/1.0.0-beta4": { - "type": "package", - "dependencies": { - "AspNet.Security.OpenIdConnect.Extensions": "1.0.0-beta4", - "Microsoft.AspNet.Authentication": "1.0.0-rc1-final", - "Microsoft.AspNet.Hosting.Abstractions": "1.0.0-rc1-final", - "Microsoft.Extensions.Caching.Abstractions": "1.0.0-rc1-final", - "Microsoft.Extensions.Logging.Abstractions": "1.0.0-rc1-final", - "Newtonsoft.Json": "7.0.1" - }, - "frameworkAssemblies": [ - "Microsoft.CSharp", - "mscorlib", - "System", - "System.Core" - ], - "compile": { - "lib/dnx451/AspNet.Security.OpenIdConnect.Server.dll": {} - }, - "runtime": { - "lib/dnx451/AspNet.Security.OpenIdConnect.Server.dll": {} - } - }, "EntityFramework.Commands/7.0.0-rc1-final": { "type": "package", "dependencies": { @@ -3223,12 +3133,12 @@ "Zlib.Portable.Signed": "1.11.0" }, "compile": { - "lib/net45/Google.Apis.dll": {}, - "lib/net45/Google.Apis.PlatformServices.dll": {} + "lib/net45/Google.Apis.PlatformServices.dll": {}, + "lib/net45/Google.Apis.dll": {} }, "runtime": { - "lib/net45/Google.Apis.dll": {}, - "lib/net45/Google.Apis.PlatformServices.dll": {} + "lib/net45/Google.Apis.PlatformServices.dll": {}, + "lib/net45/Google.Apis.dll": {} } }, "Google.Apis.Core/1.11.1": { @@ -4532,15 +4442,9 @@ "lib/net451/Microsoft.AspNet.WebUtilities.dll": {} } }, - "Microsoft.AspNetCore.Authentication.Cookies/0.0.1-alpha": { - "type": "package" - }, "Microsoft.AspNetCore.Authentication.OAuth/0.0.1-alpha": { "type": "package" }, - "Microsoft.AspNetCore.Authentication.OpenIdConnect/0.0.1-alpha": { - "type": "package" - }, "Microsoft.CodeAnalysis.Analyzers/1.0.0": { "type": "package", "frameworkAssemblies": [ @@ -5938,48 +5842,6 @@ "lib/Antlr3.Runtime.dll": {} } }, - "AspNet.Security.OpenIdConnect.Extensions/1.0.0-beta4": { - "type": "package", - "dependencies": { - "Microsoft.AspNet.Authentication": "1.0.0-rc1-final", - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "2.0.0-rc1-211161024" - }, - "frameworkAssemblies": [ - "Microsoft.CSharp", - "mscorlib", - "System", - "System.Core" - ], - "compile": { - "lib/dnx451/AspNet.Security.OpenIdConnect.Extensions.dll": {} - }, - "runtime": { - "lib/dnx451/AspNet.Security.OpenIdConnect.Extensions.dll": {} - } - }, - "AspNet.Security.OpenIdConnect.Server/1.0.0-beta4": { - "type": "package", - "dependencies": { - "AspNet.Security.OpenIdConnect.Extensions": "1.0.0-beta4", - "Microsoft.AspNet.Authentication": "1.0.0-rc1-final", - "Microsoft.AspNet.Hosting.Abstractions": "1.0.0-rc1-final", - "Microsoft.Extensions.Caching.Abstractions": "1.0.0-rc1-final", - "Microsoft.Extensions.Logging.Abstractions": "1.0.0-rc1-final", - "Newtonsoft.Json": "7.0.1" - }, - "frameworkAssemblies": [ - "Microsoft.CSharp", - "mscorlib", - "System", - "System.Core" - ], - "compile": { - "lib/dnx451/AspNet.Security.OpenIdConnect.Server.dll": {} - }, - "runtime": { - "lib/dnx451/AspNet.Security.OpenIdConnect.Server.dll": {} - } - }, "EntityFramework.Commands/7.0.0-rc1-final": { "type": "package", "dependencies": { @@ -6186,12 +6048,12 @@ "Zlib.Portable.Signed": "1.11.0" }, "compile": { - "lib/net45/Google.Apis.dll": {}, - "lib/net45/Google.Apis.PlatformServices.dll": {} + "lib/net45/Google.Apis.PlatformServices.dll": {}, + "lib/net45/Google.Apis.dll": {} }, "runtime": { - "lib/net45/Google.Apis.dll": {}, - "lib/net45/Google.Apis.PlatformServices.dll": {} + "lib/net45/Google.Apis.PlatformServices.dll": {}, + "lib/net45/Google.Apis.dll": {} } }, "Google.Apis.Core/1.11.1": { @@ -7495,15 +7357,9 @@ "lib/net451/Microsoft.AspNet.WebUtilities.dll": {} } }, - "Microsoft.AspNetCore.Authentication.Cookies/0.0.1-alpha": { - "type": "package" - }, "Microsoft.AspNetCore.Authentication.OAuth/0.0.1-alpha": { "type": "package" }, - "Microsoft.AspNetCore.Authentication.OpenIdConnect/0.0.1-alpha": { - "type": "package" - }, "Microsoft.CodeAnalysis.Analyzers/1.0.0": { "type": "package", "frameworkAssemblies": [ @@ -8904,35 +8760,8 @@ "lib/Antlr3.Runtime.pdb" ] }, - "AspNet.Security.OpenIdConnect.Extensions/1.0.0-beta4": { - "type": "package", - "sha512": "r0r4W/922xuS06pYs5dOAN2mkpRYQ4gI9LPR6IMaDulB1LAbPNmBOj7AXc4bq50A3OZgG3Cudezn6q8RJeTscw==", - "files": [ - "AspNet.Security.OpenIdConnect.Extensions.1.0.0-beta4.nupkg", - "AspNet.Security.OpenIdConnect.Extensions.1.0.0-beta4.nupkg.sha512", - "AspNet.Security.OpenIdConnect.Extensions.nuspec", - "lib/dnx451/AspNet.Security.OpenIdConnect.Extensions.dll", - "lib/dnx451/AspNet.Security.OpenIdConnect.Extensions.xml", - "lib/dnxcore50/AspNet.Security.OpenIdConnect.Extensions.dll", - "lib/dnxcore50/AspNet.Security.OpenIdConnect.Extensions.xml" - ] - }, - "AspNet.Security.OpenIdConnect.Server/1.0.0-beta4": { - "type": "package", - "sha512": "8EvftVfasTVRD2NiIuC4WTbDAUKWJr8AbCUmEyLb78tLpyFmuI1gogmmrP2gMHDIEvJyG4oJ1iXZE/xmZt3M3w==", - "files": [ - "AspNet.Security.OpenIdConnect.Server.1.0.0-beta4.nupkg", - "AspNet.Security.OpenIdConnect.Server.1.0.0-beta4.nupkg.sha512", - "AspNet.Security.OpenIdConnect.Server.nuspec", - "lib/dnx451/AspNet.Security.OpenIdConnect.Server.dll", - "lib/dnx451/AspNet.Security.OpenIdConnect.Server.xml", - "lib/dnxcore50/AspNet.Security.OpenIdConnect.Server.dll", - "lib/dnxcore50/AspNet.Security.OpenIdConnect.Server.xml" - ] - }, "EntityFramework.Commands/7.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "+wa2VWX3/vDkOpeCeIotMevqpIISimGqeYNTGYRLRhv+8HzsCLeymLzmmYpjav6zYQVvuJiJodapQvijAIfRrA==", "files": [ "app/ef", @@ -8959,7 +8788,6 @@ }, "EntityFramework.Core/7.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "afwsjOF4xM5KiwAxKMz9R0H8TigWE/jX0FwGBO/QtuA1ElEVLqlQVH4+7PyZaA35HguYRm0wOCmUq9RVTmiAfA==", "files": [ "EntityFramework.Core.7.0.0-rc1-final.nupkg", @@ -8977,7 +8805,6 @@ }, "EntityFramework.MicrosoftSqlServer/7.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "FMB2MgT5aXMF7qGMwf5AGcmpNFoT4s1w0QJ5h+L8W4gyMxWpYamGp9hms7rOSAWY44ZDl5ZMpxiTfu3nY3Nqeg==", "files": [ "EntityFramework.MicrosoftSqlServer.7.0.0-rc1-final.nupkg", @@ -8993,7 +8820,6 @@ }, "EntityFramework.Relational/7.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "0Feoct9mtKOIjovUgfESfVDL/odvxNXsIgK3bdlkx7Fsiqp5/tx8oiMx+qO7oNRYWsXN6XDlGKHLOzWEdUssKA==", "files": [ "EntityFramework.Relational.7.0.0-rc1-final.nupkg", @@ -9009,7 +8835,6 @@ }, "EntityFramework.Relational.Design/7.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "sXAqOxpHmbqOELC21vAzKlsjqgNCrk3jEjyJxjGnn1+j4hazxiqgSBTl8ZofqYzLO6ias9WfeXJy8HcXOl7waw==", "files": [ "build/netcore50/EntityFramework.Relational.Design.props", @@ -9027,7 +8852,6 @@ }, "EntityFramework.Sqlite/7.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "B+h4HHUnCSN/d4DIxW89B6q4efcZzQjajQb1yrlALEeZuCBDIzO0nrEdRZsRSNqJaNzmxRu/OsYqrZVOORUrGw==", "files": [ "EntityFramework.Sqlite.7.0.0-rc1-final.nupkg", @@ -9215,7 +9039,6 @@ }, "Microsoft.AspNet.Antiforgery/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "HpEYyzfyrnj7+13Mnn/6CgdfDVxTcg6J7PsO8rCysdrGdehbupsuZoQWerqoDRBtb0UMp0U3g0WnmAwgE2tqzA==", "files": [ "lib/dotnet5.4/Microsoft.AspNet.Antiforgery.dll", @@ -9229,7 +9052,6 @@ }, "Microsoft.AspNet.Authentication/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "sdFCeQlwkJXZ1KHsRvf7ewNEWkEeKYNpcEKKC0D+WNUvLliziLc7cMH+6sjNmTU3FgGjGrSk4WjGQMhsOHCrDQ==", "files": [ "lib/dotnet5.4/Microsoft.AspNet.Authentication.dll", @@ -9243,7 +9065,6 @@ }, "Microsoft.AspNet.Authentication.Cookies/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "vjeSG8Z5i5Kqo1nC7wW1BO+YMk+gs/AVVJlmyF7EGgiUBtAAPkrgjxSabQqvFhPgpEFledUQ6gkhKXgr4WrMtw==", "files": [ "lib/dotnet5.4/Microsoft.AspNet.Authentication.Cookies.dll", @@ -9257,7 +9078,6 @@ }, "Microsoft.AspNet.Authentication.Facebook/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "jnxn+FmMl5hteVj/9E38XLQq3ksJwTretsLJKY7qiIIpDQJqhsEPzCbop+vSalnYMMoHaFOdixWmizIQrmlOfQ==", "files": [ "lib/dotnet5.4/Microsoft.AspNet.Authentication.Facebook.dll", @@ -9271,7 +9091,6 @@ }, "Microsoft.AspNet.Authentication.JwtBearer/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "pkgJ9xKl2RY5j6alvpnLWNGpnM7qpFpcdQSSxjOFI0yWDYxkqagwghdisC/lVgRiSDzh3tm1asjpMbt+6+sNOg==", "files": [ "lib/dnx451/Microsoft.AspNet.Authentication.JwtBearer.dll", @@ -9285,7 +9104,6 @@ }, "Microsoft.AspNet.Authentication.OAuth/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "3h2Mz/ObM1pQRDDkkK4roI1Y6n6XlTQGsLxbeMQ6aGJZCYYnZhCrp6UN4CWktd3xBrLUdaRYMH1r94+0wjCqAg==", "files": [ "lib/dotnet5.4/Microsoft.AspNet.Authentication.OAuth.dll", @@ -9299,7 +9117,6 @@ }, "Microsoft.AspNet.Authentication.OpenIdConnect/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "t23VFfjomKBH7bbm0aT8Ht0QqvU5ECclpdID4lBGJ2YGEVz4t1lqxIeOO59VaSnae8LHZtoRywqOwFssF/1OQA==", "files": [ "lib/dnx451/Microsoft.AspNet.Authentication.OpenIdConnect.dll", @@ -9313,7 +9130,6 @@ }, "Microsoft.AspNet.Authentication.Twitter/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "kp0mcXaj0Vx+XY5Fwr/rDZBqs9yjzcwS6+KY3Dtk7UnmAuzVJ1Ld7/gLKkXXFzDyIh++lWfckRFQtVvV4kuydA==", "files": [ "lib/dotnet5.4/Microsoft.AspNet.Authentication.Twitter.dll", @@ -9327,7 +9143,6 @@ }, "Microsoft.AspNet.Authorization/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "zXQ4VHNDQkWzNpI05jt3laIHSlNIqROFuSbZPV7wprVi43sgeZSn9gBW5rQNcedODgsEvmsIMzl73mXzKf3TTA==", "files": [ "lib/dotnet5.4/Microsoft.AspNet.Authorization.dll", @@ -9341,7 +9156,6 @@ }, "Microsoft.AspNet.Cors/6.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "3wfAJBFtBgtYI03Oo2MHXn1bH4PgRjGjHtZ6onjuT7QevAfAgvxuqEw59r8mhW9rBz3abrgcbBwndEFef0DbCg==", "files": [ "lib/dotnet5.4/Microsoft.AspNet.Cors.dll", @@ -9355,7 +9169,6 @@ }, "Microsoft.AspNet.Cryptography.Internal/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "gQBLMaEd0ZRntSBjuWFJ6Qu3BKO6SORWA3Iv/Rhd4oEB1O8Mzdk3nHAyWyo/i8GhE740sajdwT8yXZTm3fzglg==", "files": [ "lib/dotnet5.4/Microsoft.AspNet.Cryptography.Internal.dll", @@ -9369,7 +9182,6 @@ }, "Microsoft.AspNet.Cryptography.KeyDerivation/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "a0HOA+i0gEY5SIzJZX4QXuj+hY6C7NT3t60EwreWYPAy/rruoxlkarU8H9oHwtatT2/FjC8kdMNQS72y1I/5KQ==", "files": [ "lib/dotnet5.4/Microsoft.AspNet.Cryptography.KeyDerivation.dll", @@ -9383,7 +9195,6 @@ }, "Microsoft.AspNet.DataProtection/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "HKcaIDRCz5KWkhmRiRs9mjZupJbdP3+Z3RQKdqwa6ZsXsO0ZUnmfpdYp6IFG69rTznmoSKjKJpcnvRA7w6psyA==", "files": [ "lib/dotnet5.4/Microsoft.AspNet.DataProtection.dll", @@ -9397,7 +9208,6 @@ }, "Microsoft.AspNet.DataProtection.Abstractions/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "rNCftGtK32L1R8Y3JDl31fPtYI/wppN3xngBtcQ5R8DZBfSKzabDWre95feBIKWjcPqE+P/Y7n6ax8oGFcVSZw==", "files": [ "lib/dotnet5.4/Microsoft.AspNet.DataProtection.Abstractions.dll", @@ -9411,7 +9221,6 @@ }, "Microsoft.AspNet.DataProtection.SystemWeb/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "SMCq4lwr8Vf9rMJ0HSdXux5dWILKGzmN0XuL6Uu2+aqofSeFlDhlTRg/QyiThYeFzREllLZ+iw/0P3GAhhgB0w==", "files": [ "content/net451/web.config.transform", @@ -9424,7 +9233,6 @@ }, "Microsoft.AspNet.Diagnostics/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "PlLhXpe74DUMEanyFNvo+A96zD465usPOxu2iAqREnfcpagNJY4dn6uQxDE04BY6XcqPaYAYcrZYyKRfn/pTIg==", "files": [ "lib/dotnet5.4/Microsoft.AspNet.Diagnostics.dll", @@ -9438,7 +9246,6 @@ }, "Microsoft.AspNet.Diagnostics.Abstractions/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "nr/aKzLzXFOj9KAXTh63uzxPGN4It04vh3dqnIHzKk6Bf/0kPYv9Qw3fwLQy5mc0Cka/soz5ZMdPp8IQk2BRQQ==", "files": [ "lib/dotnet5.4/Microsoft.AspNet.Diagnostics.Abstractions.dll", @@ -9452,7 +9259,6 @@ }, "Microsoft.AspNet.Diagnostics.Entity/7.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "hlOWYlYXpVSEM4wcTzNwZKvJWGUgkZQjOG12FkJFIEMyd8qT8jS20kp92kT2XeU8SBxb1kUAnTBdtOr5VRI+hQ==", "files": [ "lib/dotnet5.4/Microsoft.AspNet.Diagnostics.Entity.dll", @@ -9466,7 +9272,6 @@ }, "Microsoft.AspNet.FileProviders.Abstractions/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "Tv6YJk78cH+gFipRNjeMpzzUg3t4BQiS0xYVlv/8gVNl4sI6ytAMYYfIbx8pCacIRH5Nx/Tw9GVn28eyw+JZfA==", "files": [ "lib/dotnet5.4/Microsoft.AspNet.FileProviders.Abstractions.dll", @@ -9480,7 +9285,6 @@ }, "Microsoft.AspNet.FileProviders.Physical/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "Ni5o7X21cN97krdkg3F77F5app0KpLwdpHbxdpwqaMjhMKYcmNDcyZB8Ke/qgbSMqHRwT3aQVhgEp/iJTbgl6g==", "files": [ "lib/dotnet5.4/Microsoft.AspNet.FileProviders.Physical.dll", @@ -9494,7 +9298,6 @@ }, "Microsoft.AspNet.Hosting/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "6ZVZK5Ql+z6UeVOBcXCRLahcAd/NKdMAK17JBZWGZqqmxKO0LtQMdb6drb9H4nBM3/a8vbhd+23wxzyIfoCLQQ==", "files": [ "lib/dnx451/Microsoft.AspNet.Hosting.dll", @@ -9512,7 +9315,6 @@ }, "Microsoft.AspNet.Hosting.Abstractions/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "07N5rzYcsjkLgwoI923FcAvvf7167qhLgCExXwYYkdZUIJQzneRG0DqZJTm6qpnaD5igf4FM9F+eh2m7y5NFbg==", "files": [ "lib/dotnet5.4/Microsoft.AspNet.Hosting.Abstractions.dll", @@ -9526,7 +9328,6 @@ }, "Microsoft.AspNet.Hosting.Server.Abstractions/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "55ovPKPLsLvXsZ2xxtCOkQXmLwrE5iMUXe1y3A3Y/DCcI2u9VBJezu1y2EPYmZCM+uP/Y/BaQm68AWg2r8RV5w==", "files": [ "lib/dotnet5.4/Microsoft.AspNet.Hosting.Server.Abstractions.dll", @@ -9540,7 +9341,6 @@ }, "Microsoft.AspNet.Html.Abstractions/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "49aE5EnPr4/IBhrI5fH43o20GgqPCOZqcTDf+Ya8iVSIeorhj2Pn9e12DXqFPTKPHD7+H44K2MaU2lw1/uMiKQ==", "files": [ "lib/dotnet5.4/Microsoft.AspNet.Html.Abstractions.dll", @@ -9554,7 +9354,6 @@ }, "Microsoft.AspNet.Http/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "2vVd6xlfDKxl7pln5VOSczVo5bdJK6VLF6LR62Tb+le6e0COju7diAPHujFcXQlX/eLq2GrctN5vbIMeQ6vRTg==", "files": [ "lib/dotnet5.4/Microsoft.AspNet.Http.dll", @@ -9568,7 +9367,6 @@ }, "Microsoft.AspNet.Http.Abstractions/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "sfzc1WJMl8wGCF+rChVfJ7otT6tTv24RNXUej2r8tlQ2RDNnAozYyGb0SCW2mxpHrC31On99Wt0rksgF0c2WUw==", "files": [ "lib/dotnet5.4/Microsoft.AspNet.Http.Abstractions.dll", @@ -9582,7 +9380,6 @@ }, "Microsoft.AspNet.Http.Extensions/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "rsjbxD9W6NfqP0WNHMRyetIh6ZoKRbK1ea0V5xWdVAx53WdvgBy0HmkSwXt506+xU65jjZP19F4Ua4YjZdPHfQ==", "files": [ "lib/dotnet5.4/Microsoft.AspNet.Http.Extensions.dll", @@ -9596,7 +9393,6 @@ }, "Microsoft.AspNet.Http.Features/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "WlscfdAvN8XaaK1iv1Iewp5emei7+0SlXNkUh7kMJpeaS6K0GhwNmwqZR6VrT1oN+Maw98nEONHS34/suqQwOA==", "files": [ "lib/dotnet5.4/Microsoft.AspNet.Http.Features.dll", @@ -9610,7 +9406,6 @@ }, "Microsoft.AspNet.Identity/3.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "ACPci5zUktgGFqdZ48dWexty24lROTEW/MK3LxIDe88zssLiqMhHrIndp4G/1vafmUfL+9lTw7oda6GRD53cEg==", "files": [ "lib/dotnet5.4/Microsoft.AspNet.Identity.dll", @@ -9624,7 +9419,6 @@ }, "Microsoft.AspNet.Identity.EntityFramework/3.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "XayUdpI6mRgL4e9kowTxlYURvDGNj7FBhqbOn6uxvQwwD7gltYzKL3T07nCeSzxR5m2sJ+IvrJCMPihKrtuR5w==", "files": [ "lib/dotnet5.4/Microsoft.AspNet.Identity.EntityFramework.dll", @@ -9651,7 +9445,6 @@ }, "Microsoft.AspNet.JsonPatch/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "ymoIERwLlkXXffpKpFHZ6sjKz8HPwPqAbOnia1H3RAhyTYNJkahW6qWNXF96Fd66I1+m88pApWku+Ld0WD94Sg==", "files": [ "lib/dotnet5.4/Microsoft.AspNet.JsonPatch.dll", @@ -9665,7 +9458,6 @@ }, "Microsoft.AspNet.Localization/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "ImoAQSIWbZifALakJI5kR0l5XOBixrnnR7+7RoNfFQFvPmM6lqJv2mNEYgkpFGea/hVdfHPfsWErb1oVVnYMaw==", "files": [ "lib/dotnet5.4/Microsoft.AspNet.Localization.dll", @@ -9679,7 +9471,6 @@ }, "Microsoft.AspNet.Mvc/6.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "gKQUI2L58PibL4v/BCsML5RvpcAWQ7gNCn2xQVhLvt2fGDfRAYIr2SnalRJ0M8m+hdHDNtWydfaVrOC799zKtQ==", "files": [ "lib/dotnet5.4/Microsoft.AspNet.Mvc.dll", @@ -9693,7 +9484,6 @@ }, "Microsoft.AspNet.Mvc.Abstractions/6.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "xJH5D+h/C6KFA3XjUshgpMEznL7h018f/G4exZY76HhCfABMHmoqb5xrGKvwjKlaCwnSWPDTHeOowsGPmYZ6yQ==", "files": [ "lib/dotnet5.4/Microsoft.AspNet.Mvc.Abstractions.dll", @@ -9707,7 +9497,6 @@ }, "Microsoft.AspNet.Mvc.ApiExplorer/6.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "cFXQLFGtg8Dv8ngf42zxkqZq9jt0eV73bSFcRlyJENP+M7exk1ebCHjPt5J1wXZQkSsAmzj7JieHBEad5G3TxQ==", "files": [ "lib/dotnet5.4/Microsoft.AspNet.Mvc.ApiExplorer.dll", @@ -9721,7 +9510,6 @@ }, "Microsoft.AspNet.Mvc.Core/6.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "s4RFVnKx+c49vxu0rK33kwaff9TydQI/LI9ApgAyfZPlrjDvmzzPyKVGpfKBh682scnllaUFeOV+hL9Q6a1zJw==", "files": [ "lib/dotnet5.4/Microsoft.AspNet.Mvc.Core.dll", @@ -9735,7 +9523,6 @@ }, "Microsoft.AspNet.Mvc.Cors/6.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "HGAda11lbt59OxaFjYtzy3DOEL6VoOH4vrMJ7dGnSUbrv8hk+lbk5EUebhFxv7KcKPuoka4pdZB3CPH/TTnahg==", "files": [ "lib/dotnet5.4/Microsoft.AspNet.Mvc.Cors.dll", @@ -9749,7 +9536,6 @@ }, "Microsoft.AspNet.Mvc.DataAnnotations/6.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "1PXLllWma1/uXZJyYUWkhvMw87udjB4AfLMhVIGz2mF3KOPQgzRcdS8Eqze4ypty5+Up2QvIHBUjY2H79e2ezQ==", "files": [ "lib/dotnet5.4/Microsoft.AspNet.Mvc.DataAnnotations.dll", @@ -9763,7 +9549,6 @@ }, "Microsoft.AspNet.Mvc.Formatters.Json/6.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "orkj2uvOhyR+OuTTuewPw5F3Zi6VlU3UV3aA18wy00CwxtPJCJ4IE+J0EmLTMc/r6JGIjTF0pgABsgD0EzhrPg==", "files": [ "lib/dotnet5.4/Microsoft.AspNet.Mvc.Formatters.Json.dll", @@ -9777,7 +9562,6 @@ }, "Microsoft.AspNet.Mvc.Localization/6.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "G5omyQF/PJZmUrhnuaXxvIpfkp8OgU1fwwBZfsnlaaJd7h8gOhkQspdbXQB+UP5lGO1J/ypFUOYuYmVRKmEjyg==", "files": [ "lib/dotnet5.4/Microsoft.AspNet.Mvc.Localization.dll", @@ -9791,7 +9575,6 @@ }, "Microsoft.AspNet.Mvc.Razor/6.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "zkC6r/If5OoGsDJLkDY+O16K+WirFi2ZBgPbG8cHr3ybnlR4/u8S0p9bqnOd191kibxAAYKYfafVg+NApv8Vig==", "files": [ "lib/dotnet5.4/Microsoft.AspNet.Mvc.Razor.dll", @@ -9805,7 +9588,6 @@ }, "Microsoft.AspNet.Mvc.Razor.Host/6.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "kYvYr+IAe91NgHPARMkGSLQzep3Zs7gHJCtAhslcmU8cDJaodoUxVxJikiBX9HmZIzKf9uENT8Et5JCWpQFqRA==", "files": [ "lib/dotnet5.4/Microsoft.AspNet.Mvc.Razor.Host.dll", @@ -9819,7 +9601,6 @@ }, "Microsoft.AspNet.Mvc.TagHelpers/6.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "zcoDzmKSMdOVUQHQZJQStArNqc5ERTxosB3GiK/MbC0HFhJ4vmh/vwI0rxnXO6X25+gYnr/2PAiY9fHvGkN58A==", "files": [ "lib/dotnet5.4/Microsoft.AspNet.Mvc.TagHelpers.dll", @@ -9833,7 +9614,6 @@ }, "Microsoft.AspNet.Mvc.ViewFeatures/6.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "IoWtyV9HXJ1x2HKXpcqX25iPOHAmW9vlQJD3bliMV5Oix3sjieVK7i2S3VpUsJjqddpSA9Vg2PkQIzwDDS+smA==", "files": [ "lib/dotnet5.4/Microsoft.AspNet.Mvc.ViewFeatures.dll", @@ -9847,7 +9627,6 @@ }, "Microsoft.AspNet.Owin/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "6lkzV/uEYORT1GQDddWVjsm/zRtEZHnIcWmBR4H6tqjsv1q2rWFmDy8rEckPvxUVn1iNTWKpn6s4UJglbdTgtg==", "files": [ "lib/dotnet5.4/Microsoft.AspNet.Owin.dll", @@ -9861,7 +9640,6 @@ }, "Microsoft.AspNet.PageExecutionInstrumentation.Interfaces/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "+goR2yw/UKbZGXvnR9z+mLWoAt2+AcDwE65XoV0HyYDyvvF+hotNiI5Ft0P/kVr8gpLeHS3JHHdRtsCjIqxhDQ==", "files": [ "lib/dotnet5.4/Microsoft.AspNet.PageExecutionInstrumentation.Interfaces.dll", @@ -9875,7 +9653,6 @@ }, "Microsoft.AspNet.Razor/4.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "j4R032B5HY3WjgGir8/Zer2FWZzsux8SS1fD6AugKmI7Msx/4d8/0FCMRbLCFNytt2rosOmNJhoAp7qOlzOHVw==", "files": [ "lib/dotnet5.4/Microsoft.AspNet.Razor.dll", @@ -9889,7 +9666,6 @@ }, "Microsoft.AspNet.Razor.Runtime/4.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "UQSVaYFnLiSI3gtb6Q2jSv3yZia+vmve/TQrprlXUT5jAeUJa5G2DWYTcGPZE6BfmAim5SZ1BOW6ozMLRBHQ/Q==", "files": [ "lib/dotnet5.4/Microsoft.AspNet.Razor.Runtime.dll", @@ -9903,7 +9679,6 @@ }, "Microsoft.AspNet.Razor.Runtime.Precompilation/4.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "3YD0OJRtuYgBQX6OBLNxZf8VdOQ7nv5TlA1frq0WOuS+7KMXJj+3oS69YwJ65x4zCRpUkl2bHCFTC4X7nG4KSw==", "files": [ "lib/dotnet5.4/Microsoft.AspNet.Razor.Runtime.Precompilation.dll", @@ -9917,7 +9692,6 @@ }, "Microsoft.AspNet.Routing/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "kIDLp1Icd+l2Z5jFGZf5rAKALS2btMKdP+a+zOepiE4oZJCAJ5tWms+MyMkMJ8hD9/5O6fF4CzckBBcA6pxNUQ==", "files": [ "lib/dotnet5.4/Microsoft.AspNet.Routing.dll", @@ -9931,7 +9705,6 @@ }, "Microsoft.AspNet.Server.Kestrel/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "4fuGqW9K2PaxLwQsyRZaoO2Eu+GT5nv8WeYWpD8EqHLzY9GVEW25jy1iW2+1Tf5BwQJLN2e9QxY2K7OPlM9iRg==", "files": [ "lib/dnx451/Microsoft.AspNet.Server.Kestrel.dll", @@ -9954,7 +9727,6 @@ }, "Microsoft.AspNet.Server.WebListener/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "U1S48H06oKFHVth/1xUtylpa0E4tBDYtxpzfELeZ1aNW3fdOqcd20dlh6bapOP78R+axSY1DI/FR8dGGgn+84Q==", "files": [ "lib/dnx451/Microsoft.AspNet.Server.WebListener.dll", @@ -9972,7 +9744,6 @@ }, "Microsoft.AspNet.Session/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "nMImkPMx/z4YL/bCBaTywQZD28sg6IvWMRckzY4hMZuhhRWr4z3HHYgORCaKbJQH3nJkfL6rb+TpmWobN9gKpw==", "files": [ "lib/dotnet5.4/Microsoft.AspNet.Session.dll", @@ -9986,7 +9757,6 @@ }, "Microsoft.AspNet.SignalR.Core/2.2.0": { "type": "package", - "serviceable": true, "sha512": "y+gx2iv3Da2YIkh/m8BSitF63PAs7sDJY9td9blvgrXzCvKAb664sc/2D7kNSwEiFDLDGCoax6pqe3pRRDSDHQ==", "files": [ "lib/net45/Microsoft.AspNet.SignalR.Core.dll", @@ -10009,7 +9779,6 @@ }, "Microsoft.AspNet.SignalR.Owin/1.2.2": { "type": "package", - "serviceable": true, "sha512": "LmR0YFPkuBq9MG4NkyL9UR8rMaiBwrjgjc0L+ttsGoAKU5VXfPD+dBWhbZJedUZjvIDwgcEuKCePkNnvvqLetg==", "files": [ "lib/net40/Microsoft.AspNet.SignalR.Owin.dll", @@ -10023,7 +9792,6 @@ }, "Microsoft.AspNet.StaticFiles/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "JKFrKL6iwGzG+DO9vwP8fEbz3gHA9K6SoCE/Th/oIwxDEENNF2TAYjjAag5c0iJcaK3+X8+s2RkA/zZ+vWHOTg==", "files": [ "lib/dotnet5.4/Microsoft.AspNet.StaticFiles.dll", @@ -10037,7 +9805,6 @@ }, "Microsoft.AspNet.Tooling.Razor/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "ZWDxJ4sqrZyrtmlRKeBYrxguRNBnTGV2LNgyZrSyVQ8DcQjPkSqFwu18BeER+j6Od2mgV5aOCdCLDN0QnjYI7Q==", "files": [ "app/project.json", @@ -10065,7 +9832,6 @@ }, "Microsoft.AspNet.WebSockets.Protocol/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "dc/e2uVh/J9dQ9DuXh0hlTSS5lID2Kr+O+EFgf9NgrvP1sFS8EWDGHoUv9RS/owVfFtd956bnRjMX2jD/5NBPA==", "files": [ "lib/dotnet5.4/Microsoft.AspNet.WebSockets.Protocol.dll", @@ -10079,7 +9845,6 @@ }, "Microsoft.AspNet.WebSockets.Server/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "hVPS2eewqM8S5cpFK62+d10WCaPBQb9pnP3ahEYP/wMlycv0nAmsQ5sMeaI06zI12cZTAXWnwf3aUgN7/2yuFA==", "files": [ "lib/dotnet5.4/Microsoft.AspNet.WebSockets.Server.dll", @@ -10093,7 +9858,6 @@ }, "Microsoft.AspNet.WebUtilities/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "0D80xroAEiWlB9X5eR/JUya1H2saIYnt4d7bPru5RRf5L/66X+9WWhf3hFkLUF3W13K6g6K9Is9dCTaEfFFKTA==", "files": [ "lib/dotnet5.4/Microsoft.AspNet.WebUtilities.dll", @@ -10105,16 +9869,6 @@ "Microsoft.AspNet.WebUtilities.nuspec" ] }, - "Microsoft.AspNetCore.Authentication.Cookies/0.0.1-alpha": { - "type": "package", - "sha512": "HLC6HZEnJpRX6HFHAYngQEYSx30Py0r4Jcl2kP/KOR4Ctc1oDLoDDCKc5y7NE/Rck7Hj+2tZ0RO8cDvtyMOlRQ==", - "files": [ - "content/Readme.txt", - "Microsoft.AspNetCore.Authentication.Cookies.0.0.1-alpha.nupkg", - "Microsoft.AspNetCore.Authentication.Cookies.0.0.1-alpha.nupkg.sha512", - "Microsoft.AspNetCore.Authentication.Cookies.nuspec" - ] - }, "Microsoft.AspNetCore.Authentication.OAuth/0.0.1-alpha": { "type": "package", "sha512": "CRa90T3SrbRqYRA1libMqoLZjpQy6QirJ6/IdYJ7LSyDHuwqRSK3583Q6dJovigGGv95MdGUTVMz0iD68FcW5w==", @@ -10125,16 +9879,6 @@ "Microsoft.AspNetCore.Authentication.OAuth.nuspec" ] }, - "Microsoft.AspNetCore.Authentication.OpenIdConnect/0.0.1-alpha": { - "type": "package", - "sha512": "VYVragg1EADQIdmMzgmttXXk1wk8D054oH26fG9p/cpBzQuYf0i2TsgkVfYuA+xF0kPdBeE1r6s4pLgbMLoHNQ==", - "files": [ - "content/Readme.txt", - "Microsoft.AspNetCore.Authentication.OpenIdConnect.0.0.1-alpha.nupkg", - "Microsoft.AspNetCore.Authentication.OpenIdConnect.0.0.1-alpha.nupkg.sha512", - "Microsoft.AspNetCore.Authentication.OpenIdConnect.nuspec" - ] - }, "Microsoft.CodeAnalysis.Analyzers/1.0.0": { "type": "package", "sha512": "E7VdmGw6xO3VHWapC+pNLZmo6yncS53UY3bmb5WZm9wliJBB1A6brgzKA4fcqiLrmJFx71r0M2zEbRDphRLUNg==", @@ -10181,7 +9925,6 @@ }, "Microsoft.Data.Sqlite/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "54F32OBWIWMIpeKggCMEX+Bp/TiAiKzBaQ4z+IRr61eNSnJhxMnLE/QWDs5YbCtbDlWIB4+VBC1rnT8PFGCtdw==", "files": [ "build/net451/Microsoft.Data.Sqlite.props", @@ -10204,7 +9947,6 @@ }, "Microsoft.Dnx.Compilation.Abstractions/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "kg3kR7H12Bs46TiuF7YT8A3SNXehhBcwsArIMQIH2ecXGkg5MPWDl2OR6bnQu6k0OMu9QUiv1oiwC9yU7rHWfw==", "files": [ "lib/dotnet5.4/Microsoft.Dnx.Compilation.Abstractions.dll", @@ -10218,7 +9960,6 @@ }, "Microsoft.Dnx.Compilation.CSharp.Abstractions/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "MYJJHSIqOvmQxm2KOCwfber5JUwYKtfMREVYxnj/kv+HQrfrztL9dN4IFvh/SsBzm5cGR0Lt52bWJKzkrIRF/g==", "files": [ "lib/dotnet5.4/Microsoft.Dnx.Compilation.CSharp.Abstractions.dll", @@ -10232,7 +9973,6 @@ }, "Microsoft.Dnx.Compilation.CSharp.Common/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "/OnNSw+oX/sc3Rl1Q9vFMhg+OPC+AbaDYmC4JufkHop8Ydhsv94JDT4w5xrpXi7QIKICQGTyzQgAkUjPnuFzdA==", "files": [ "lib/dotnet5.4/Microsoft.Dnx.Compilation.CSharp.Common.dll", @@ -10246,7 +9986,6 @@ }, "Microsoft.Extensions.Caching.Abstractions/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "WlNfPuf/8Q7DzMiOHjiT9Ha2IYdguLGfHT/2C/p9KzviCKXaqfrIdI6X9w5MmCuiYRucqK+iM5cIWKHQ1mmZrg==", "files": [ "lib/dotnet5.4/Microsoft.Extensions.Caching.Abstractions.dll", @@ -10262,7 +10001,6 @@ }, "Microsoft.Extensions.Caching.Memory/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "KQFkXdBieLObHr1+ld0FVOLQLgVFcrhn6qIixsmP09TyEw2VaGPrzIiBVJSzyKfaE2MVJlshDvfdvcfSE/zl3g==", "files": [ "lib/dotnet5.4/Microsoft.Extensions.Caching.Memory.dll", @@ -10278,7 +10016,6 @@ }, "Microsoft.Extensions.CodeGeneration/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "Mkld1xqSkU1CuMtMlbKMPwzoXMXBzC/SdOiRLutd632mGrQCDwhBgrxiBDfFDD63OxWt24TjMZkqlxmRRTm7zQ==", "files": [ "lib/dnx451/Microsoft.Extensions.CodeGeneration.dll", @@ -10292,7 +10029,6 @@ }, "Microsoft.Extensions.CodeGeneration.Core/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "uQe19xMM4ymoC9uU/rLZTkbSH8n/CVKEjw4jbLfoFq179+LH4IxDRqPqidEMQUF6ON4jYVwhexuAMPJdQ5ewjQ==", "files": [ "lib/dnx451/Microsoft.Extensions.CodeGeneration.Core.dll", @@ -10306,7 +10042,6 @@ }, "Microsoft.Extensions.CodeGeneration.EntityFramework/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "Bs5bPxbPlTYAB5d1+bPjnAZqQyQMueg0orED8boIlwb66he5pFO7LuQ3Q+BNTUB4x3M1q1U7L1L469tllVtGZg==", "files": [ "lib/dnx451/Microsoft.Extensions.CodeGeneration.EntityFramework.dll", @@ -10321,7 +10056,6 @@ }, "Microsoft.Extensions.CodeGeneration.Templating/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "d20Suo15M+sNS5QBYMfJpBgSUFclVSeIU06Y/snnmKdNjAiQfbKkW0bG8ryBw8zn29KXHcK39DwUpkrFvphQIg==", "files": [ "lib/dnx451/Microsoft.Extensions.CodeGeneration.Templating.dll", @@ -10335,7 +10069,6 @@ }, "Microsoft.Extensions.CodeGenerators.Mvc/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "rkec5T1UW17vRb6rPWEDOq4WHj7+mu8IKWuea9I05YKDACo/EBgDhqp4aoZrOsNzoEH6k+NlL0FRa3o5s9vglA==", "files": [ "lib/dnx451/Microsoft.Extensions.CodeGenerators.Mvc.dll", @@ -10380,7 +10113,6 @@ }, "Microsoft.Extensions.Configuration/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "2ayWzqMVGWjr8o8bOSnIsyQbi9sLz9Ya8+YM+9tM/ivSnLHuN7TNHNfJv4jTyRZvoOafdh5Ivlc/OdmsZPXlQQ==", "files": [ "lib/dotnet5.4/Microsoft.Extensions.Configuration.dll", @@ -10396,7 +10128,6 @@ }, "Microsoft.Extensions.Configuration.Abstractions/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "xA7ObOlIswcx2qakv69kz0pnBizFJrmwxRxJyjPOHWfevF4W+OdolZsbKOc12kY7y5upqhAvNGWTblffMvADHA==", "files": [ "lib/dotnet5.4/Microsoft.Extensions.Configuration.Abstractions.dll", @@ -10412,7 +10143,6 @@ }, "Microsoft.Extensions.Configuration.Binder/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "tuIi7cRq6lbpCybL+z9vamz/KbM+nN9nyJ2Id5bKCdxKDNMnKb9PdMxJ+0DHc8p6fP00PyQucYuN5EpxsYrX6Q==", "files": [ "lib/dotnet5.4/Microsoft.Extensions.Configuration.Binder.dll", @@ -10428,7 +10158,6 @@ }, "Microsoft.Extensions.Configuration.CommandLine/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "k+kXsefuLV5WkkG6X8GFn9zf9ZrMyC3dddgm6I6scpbanDyoKUYrRUP2VhW0ViO6TIva0soh6jJy3pFPCrNx9Q==", "files": [ "lib/dotnet5.4/Microsoft.Extensions.Configuration.CommandLine.dll", @@ -10444,7 +10173,6 @@ }, "Microsoft.Extensions.Configuration.EnvironmentVariables/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "CaNirkiOycy0L6ptGxmpDkHZ2lzqcHKDbQJBfEhobnEt43pqKGKgAPC5dW3DfnsMpuK+inypm5iht9t6tq4vjg==", "files": [ "lib/dotnet5.4/Microsoft.Extensions.Configuration.EnvironmentVariables.dll", @@ -10460,7 +10188,6 @@ }, "Microsoft.Extensions.Configuration.FileExtensions/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "w2x8nqrp2YUgNBJuZ3SUmexBtjaoZFzCQtObRTjrE4GWceFEmaLZtXFvs4n9IgRQkOqqCza7Fv7NXnD9m2emjQ==", "files": [ "lib/dotnet5.4/Microsoft.Extensions.Configuration.FileExtensions.dll", @@ -10476,7 +10203,6 @@ }, "Microsoft.Extensions.Configuration.FileProviderExtensions/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "OhIrGyCmuWalr0WEAtoRarpTTxP/hb4CHHvv15KYjzgB91T5In2PMaBX65Y0pBxvhKqPdocvo8iNOh2Sk+abNw==", "files": [ "lib/dotnet5.4/Microsoft.Extensions.Configuration.FileProviderExtensions.dll", @@ -10492,7 +10218,6 @@ }, "Microsoft.Extensions.Configuration.Json/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "9v+RpswnXEpAP5mx8J1w1yZZT2pPtMBTnOAauNh2c9ju5Dhq3ljxvbm0S9j6o5F/EFSLlbfN/brxTJN3qa/upw==", "files": [ "lib/dotnet5.4/Microsoft.Extensions.Configuration.Json.dll", @@ -10508,7 +10233,6 @@ }, "Microsoft.Extensions.Configuration.UserSecrets/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "m2WaXGNWRrbpWquen8PS1oB8GdG5tCSWhXAmFbhacj1mhz3ojFy0TDUZPbx87TX2ZQNNp6MYfzO5Z73hlM47Bw==", "files": [ "lib/dotnet5.4/Microsoft.Extensions.Configuration.UserSecrets.dll", @@ -10522,7 +10246,6 @@ }, "Microsoft.Extensions.DependencyInjection/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "S/+s3fq85j21H5nYOvh1fIt1arl8F5lZ7Ryiw/qend83yHQwIQbBs+dip9FhqiPmAn6Dz3UhW0likQQurfEsLQ==", "files": [ "lib/dotnet5.4/Microsoft.Extensions.DependencyInjection.dll", @@ -10538,7 +10261,6 @@ }, "Microsoft.Extensions.DependencyInjection.Abstractions/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "MUKexXAsRZ55C7YZ26ShePZgBeW+6FbasxeIVmZ/BZIgiG4uw6yPOdfl9WvTaUL9SFK2sEPcYLatWmLfTpsOAA==", "files": [ "lib/dotnet5.4/Microsoft.Extensions.DependencyInjection.Abstractions.dll", @@ -10554,7 +10276,6 @@ }, "Microsoft.Extensions.FileSystemGlobbing/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "7N9IPDU0T1uQBj6hobeGNqiEd+Cuu6RHJ0RcwkUvzTsLq8Vf2Sc72+HEAICTw1CTRXHgW49Zr47PvO0QPxI/5g==", "files": [ "lib/dotnet5.4/Microsoft.Extensions.FileSystemGlobbing.dll", @@ -10568,7 +10289,6 @@ }, "Microsoft.Extensions.Globalization.CultureInfoCache/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "HZggxvkQz5r5Dp36eCdnV8A/fmuhlK2xxmSnUKPES4w3l0C8mzbRLoJlPVdxyd9xy00odSlS5tz8w2IegZcqBQ==", "files": [ "lib/dotnet5.4/Microsoft.Extensions.Globalization.CultureInfoCache.dll", @@ -10582,7 +10302,6 @@ }, "Microsoft.Extensions.Localization/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "nt1CcD9lUXyYl0Y+ecAr2DtPI3rRCs5f1zUKRl5rN8SFOXHXK21V6kycFVP+VckUD39jsTTLuxKSKGCuBZ/9+Q==", "files": [ "lib/dotnet5.4/Microsoft.Extensions.Localization.dll", @@ -10596,7 +10315,6 @@ }, "Microsoft.Extensions.Localization.Abstractions/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "0Z6Knet4Re5ZLIpixjLX9w8TrTPjsB3F/b9EIN1RdX5inXkdOrnpgiT6j/PzcgUcCNlCXe1dTqutVSDE6+26ig==", "files": [ "lib/dotnet5.4/Microsoft.Extensions.Localization.Abstractions.dll", @@ -10610,7 +10328,6 @@ }, "Microsoft.Extensions.Logging/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "anegHH4XHjaCmC557A0uvnJzprT44MOKr669yfiQLtITA+lQrM3aMijxjjdCREnxE8ftXuSz+6wViCvkgcAOhA==", "files": [ "lib/dotnet5.4/Microsoft.Extensions.Logging.dll", @@ -10626,7 +10343,6 @@ }, "Microsoft.Extensions.Logging.Abstractions/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "ejGO1JhPXMsCCSyH12xwkOYsb9oBv2gHc3LLaT2jevrD//xuQizWaxpVk0/rHGdORkWdp+kT2Qmuz/sLyNWW/g==", "files": [ "lib/dotnet5.4/Microsoft.Extensions.Logging.Abstractions.dll", @@ -10642,7 +10358,6 @@ }, "Microsoft.Extensions.Logging.Console/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "zUklTASL2my5gp291VZuK6YMLit9ECmU7gDNN/gDwqO3EB1CDyKQtGQBtABNNgJw/0In8mFFNbsiGYhZ8xFUJA==", "files": [ "lib/dotnet5.4/Microsoft.Extensions.Logging.Console.dll", @@ -10658,7 +10373,6 @@ }, "Microsoft.Extensions.Logging.Debug/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "MBBASQ1nP6TeQndLQIr2iBYicVwZB64T14cnsvTuiWsV/aj5nFtR23hLYOJL2JJkrkU25/1/knxDpfH+0vG96g==", "files": [ "lib/dotnet5.4/Microsoft.Extensions.Logging.Debug.dll", @@ -10674,7 +10388,6 @@ }, "Microsoft.Extensions.MemoryPool/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "QaWADlihqf1DDDLqav1v5u7ObNF7qqPpt4CyN7xBwSx0/jhFjtDnFnKswNYgC/kNFJWZ+crF22AR19M3LlQRaQ==", "files": [ "lib/dotnet5.4/Microsoft.Extensions.MemoryPool.dll", @@ -10698,7 +10411,6 @@ }, "Microsoft.Extensions.OptionsModel/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "IhK5pNqRgakrwiv5OrB6hv7e6+TZzYqfJr40Qri0Xgi+oXJklNgbA5eHvzZrghdHfqfSqcvLWtWD0ri6e8Eo1w==", "files": [ "lib/dotnet5.4/Microsoft.Extensions.OptionsModel.dll", @@ -10714,7 +10426,6 @@ }, "Microsoft.Extensions.PlatformAbstractions/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "26HS4c6MBisN+D7XUr8HObOI/JJvSJQYQR//Bfw/hi9UqhqK3lFpNKjOuYHI+gTxYdXT46HqZiz4D+k7d+ob3A==", "files": [ "lib/dotnet5.4/Microsoft.Extensions.PlatformAbstractions.dll", @@ -10728,7 +10439,6 @@ }, "Microsoft.Extensions.Primitives/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "oHWqBARJveyM7LctuqQqvsTC58hxoq0gGnHr6Qsxie71LIkZpfE21IklhSLOsqmv4QIpes/G6k1vZbAQ+cC/nw==", "files": [ "lib/dotnet5.4/Microsoft.Extensions.Primitives.dll", @@ -10744,7 +10454,6 @@ }, "Microsoft.Extensions.WebEncoders/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "wzBnlP/2tFePKvM+DNyRuf6mWt9BxCRjdQBFi+9xUz0DhFdhMzLKN97ZE9/fd36rUVjd2JwlGqHUOSYQURNhfw==", "files": [ "lib/dotnet5.4/Microsoft.Extensions.WebEncoders.dll", @@ -10758,7 +10467,6 @@ }, "Microsoft.Extensions.WebEncoders.Core/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "wt47w3Zu7JvuD7CfRSCaz0IZL5EzpuzicRm6Qcidteb2TVeB98Psg7YGiwIBeYB1b52YFTBgqC+ySKk/GRhy2A==", "files": [ "lib/dotnet5.4/Microsoft.Extensions.WebEncoders.Core.dll", @@ -10772,7 +10480,6 @@ }, "Microsoft.Framework.Configuration/1.0.0-beta8": { "type": "package", - "serviceable": true, "sha512": "M2Fg4gBigELMjFow/w44eGZe7VICY6naOe8R6jKbtsXpDTKFsfCuXxpZcUfIgI791hs7Ney88IjxZ3XudsgJeg==", "files": [ "lib/dnx451/Microsoft.Framework.Configuration.dll", @@ -10790,7 +10497,6 @@ }, "Microsoft.Framework.Configuration.Abstractions/1.0.0-beta8": { "type": "package", - "serviceable": true, "sha512": "WH5zC6AkShx6VZzZT37tl0QPROkR6zdffACEIPiDyPyqyf+DtWN5Z6v1q9OD5q6CfAij18EwqWaF1eWtYBigNw==", "files": [ "lib/dnx451/Microsoft.Framework.Configuration.Abstractions.dll", @@ -10808,7 +10514,6 @@ }, "Microsoft.Framework.Configuration.Binder/1.0.0-beta8": { "type": "package", - "serviceable": true, "sha512": "6BWMPvDuy6nTe32z2JWsoiLljVhWagWkDhcN9EbvN4/ihGbnCWzKPIUCJ3a/1s9k/ZsWp4VZtxeuSaZ+60qQbQ==", "files": [ "lib/dnx451/Microsoft.Framework.Configuration.Binder.dll", @@ -10826,7 +10531,6 @@ }, "Microsoft.Framework.Configuration.FileExtensions/1.0.0-beta8": { "type": "package", - "serviceable": true, "sha512": "+hsytl/Puj6Gc6U934Y7n3hfdkJG7lfvasIwY0RnAmsTSxJ6pF54A/mR3d/EwSHyUyMlgSnSHeoTXZ4u8RfJsA==", "files": [ "lib/dnx451/Microsoft.Framework.Configuration.FileExtensions.dll", @@ -10842,7 +10546,6 @@ }, "Microsoft.Framework.Configuration.Json/1.0.0-beta8": { "type": "package", - "serviceable": true, "sha512": "dfA9iuKWri9gVaAY7XEQMXP5C+PMalC+0vDhv9AUuawwuTeQm11JhOwXzdPu/FM4Bbwm33kHlVkLrHRW403XIA==", "files": [ "lib/dnx451/Microsoft.Framework.Configuration.Json.dll", @@ -10860,7 +10563,6 @@ }, "Microsoft.Framework.ConfigurationModel/1.0.0-beta4": { "type": "package", - "serviceable": true, "sha512": "VD5MhmQRhYVfxyDs1fyruPTj3pYwLMV5dXJkPUVg1KKbJ9qr/tEn3frJA1NN1jdeVBt1RrW5FXr+wWG9YoO9Yg==", "files": [ "lib/dnx451/Microsoft.Framework.ConfigurationModel.dll", @@ -10878,7 +10580,6 @@ }, "Microsoft.Framework.ConfigurationModel.Interfaces/1.0.0-beta4": { "type": "package", - "serviceable": true, "sha512": "lU9+gyEz+jSeR+QsZxZtDf0U2DS/pl3I8/m7YeKjHMnjqoxUKFbSOpzegll7bhq0Alw7/8gF2Byrcy+PlzRc/g==", "files": [ "lib/dnx451/Microsoft.Framework.ConfigurationModel.Interfaces.dll", @@ -10896,7 +10597,6 @@ }, "Microsoft.Framework.ConfigurationModel.Json/1.0.0-beta4": { "type": "package", - "serviceable": true, "sha512": "ygdShf5lzRsqe7/pMNSaiq6AcAy0eIhp8WFUtYfqQnsxhMJFcw/VlIFvie8+DkYhacdmGkXTF4OGopjjwfg02A==", "files": [ "lib/dnx451/Microsoft.Framework.ConfigurationModel.Json.dll", @@ -10912,7 +10612,6 @@ }, "Microsoft.Framework.DependencyInjection/1.0.0-beta8": { "type": "package", - "serviceable": true, "sha512": "6TmUFq/mt2l7QKoDyCuJOrDFcJ9A3ljZ/P3SBQMb+IYJ9J7XivUb47E+E9dQXhIjs5FpFHUGAE5Mxj2oKpxkfA==", "files": [ "lib/dnx451/Microsoft.Framework.DependencyInjection.dll", @@ -10930,7 +10629,6 @@ }, "Microsoft.Framework.DependencyInjection.Abstractions/1.0.0-beta8": { "type": "package", - "serviceable": true, "sha512": "7WL9hy+7bYDyBtIrrW5tw57dChBcizjSyuD0p5pVkay+gSseLqvAk72a4KldMmRgH//7t74d/YVrTvLhw83b7w==", "files": [ "lib/dnx451/Microsoft.Framework.DependencyInjection.Abstractions.dll", @@ -10948,7 +10646,6 @@ }, "Microsoft.Framework.Runtime.Interfaces/1.0.0-beta4": { "type": "package", - "serviceable": true, "sha512": "RrZdqvUm8QbgxnZQuafYGo6NezoKx7VqAfAtHVzoKBm3GSV8xlPh90u1fsGhNCv37xJNk5PuRCa4Mq27ko7pLw==", "files": [ "lib/dnx451/Microsoft.Framework.Runtime.Interfaces.dll", @@ -10962,7 +10659,6 @@ }, "Microsoft.IdentityModel.Logging/1.0.0-rc1-211161024": { "type": "package", - "serviceable": true, "sha512": "creXwpCysjVpRx+IsZSf8mxCT9lZ/VY1T6wR6zFFulPXV1UZysVURmLd/IgJg/p9pAtcrU5yIbRC9Az3j73+nA==", "files": [ "lib/dotnet5.4/Microsoft.IdentityModel.Logging.dll", @@ -10976,7 +10672,6 @@ }, "Microsoft.IdentityModel.Protocols/2.0.0-rc1-211161024": { "type": "package", - "serviceable": true, "sha512": "1/I4nkZCKjNg9jIASv2sNIi8RvdsYLi/efbylZEw+zvtBgNfNEvdCeAsIVyX3A4pR0yQwtIdz+kTYRTs2diSEQ==", "files": [ "lib/dotnet5.4/Microsoft.IdentityModel.Protocols.dll", @@ -10990,7 +10685,6 @@ }, "Microsoft.IdentityModel.Protocols.OpenIdConnect/2.0.0-rc1-211161024": { "type": "package", - "serviceable": true, "sha512": "4xW6TBJ4ys3p+KtHwzddq8pkdxFoUtRlHYcHECK9YtZxkp4omLA9NUGrHRZ57RGN31vPdSzX3u1ujiA2Bqpo+A==", "files": [ "lib/dotnet5.4/Microsoft.IdentityModel.Protocols.OpenIdConnect.dll", @@ -11004,7 +10698,6 @@ }, "Microsoft.Net.Http.Headers/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "Y10hkmHQZLieW3J6J+vTiq86vifmJ7Vc2zrwNR349oAaUGjTHL0ws6rqHn0JDIcawBna4AE3OBNsL9vuZuE8bw==", "files": [ "lib/dotnet5.4/Microsoft.Net.Http.Headers.dll", @@ -11018,7 +10711,6 @@ }, "Microsoft.Net.Http.Server/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "XQMZUf0SbVzjTX0vyiVr0LP3Cygy1wCPDZmDla9Yeqc07HvSZ02Sg4qTSKiNV2h85yY3Dka+MNmL3XoYmnsEAA==", "files": [ "lib/dotnet5.4/Microsoft.Net.Http.Server.dll", @@ -11032,7 +10724,6 @@ }, "Microsoft.Net.WebSockets/1.0.0-rc1-final": { "type": "package", - "serviceable": true, "sha512": "DIzmA7s2sNBEq+Wz5cCPFAYKx1WGiLE7iCVrA7Lvhxf/+EzPWeaKlCYvjSHTPNViZsX/eUI5vsiDmqK/5tZjQA==", "files": [ "lib/dotnet5.4/Microsoft.Net.WebSockets.dll", @@ -11066,7 +10757,6 @@ }, "Microsoft.Owin/2.1.0": { "type": "package", - "serviceable": true, "sha512": "lk0kK64mlmcmtWX8YOYkZsnZKDoGEzMZhe8e1bcP+FFcgD4f2QfKwvu5Z8Bh8WS0VO7Rgk+DJ0hwW0k+S/UGMg==", "files": [ "lib/net40/Microsoft.Owin.dll", @@ -11080,7 +10770,6 @@ }, "Microsoft.Owin.Security/2.1.0": { "type": "package", - "serviceable": true, "sha512": "4n1V0p+O6W1L0xHUM8Cjp2Y+MmmUkiCZv6PvRNIDCJD9zlerBJa2HECo9lUiWC+KuasQJ3QxB1FmipNBxdXXIQ==", "files": [ "lib/net45/Microsoft.Owin.Security.dll", @@ -11155,7 +10844,6 @@ "lib/portable-net40+sl5+wp80+win8+wpa81/Newtonsoft.Json.xml", "lib/portable-net45+wp80+win8+wpa81+dnxcore50/Newtonsoft.Json.dll", "lib/portable-net45+wp80+win8+wpa81+dnxcore50/Newtonsoft.Json.xml", - "Newtonsoft.Json.7.0.1.nupkg", "Newtonsoft.Json.7.0.1.nupkg.sha512", "Newtonsoft.Json.nuspec", "tools/install.ps1" @@ -11282,7 +10970,6 @@ }, "System.Collections.Immutable/1.1.37": { "type": "package", - "serviceable": true, "sha512": "fTpqwZYBzoklTT+XjTRK8KxvmrGkYHzBiylCcKyQcxiOM8k+QvhNBxRvFHDWzy4OEP5f8/9n+xQ9mEgEXY+muA==", "files": [ "lib/dotnet/System.Collections.Immutable.dll", @@ -11452,7 +11139,6 @@ }, "System.IdentityModel.Tokens/5.0.0-rc1-211161024": { "type": "package", - "serviceable": true, "sha512": "UbFu6NIPI8pDL/lZlajUQ06OQNJvkpUWYBDIZr+HaqiXseE0Jja1kXTFg2gxKpjuruRinR7e7+/qnAAE3/BPcw==", "files": [ "lib/dotnet5.4/System.IdentityModel.Tokens.dll", @@ -11466,7 +11152,6 @@ }, "System.IdentityModel.Tokens.Jwt/5.0.0-rc1-211161024": { "type": "package", - "serviceable": true, "sha512": "A/mqsC0pFbFnsZ6OR17PPkNz4OEu0Xt8wK83FNDLvsoWMhvKS2DDFnn9dqzUxKDLEIZUXwWWCJQJritmvXsf1g==", "files": [ "lib/dotnet5.4/System.IdentityModel.Tokens.Jwt.dll", @@ -11528,7 +11213,6 @@ }, "System.Linq/4.0.0": { "type": "package", - "serviceable": true, "sha512": "r6Hlc+ytE6m/9UBr+nNRRdoJEWjoeQiT3L3lXYFDHoXk3VYsRBCDNXrawcexw7KPLaH0zamQLiAb6avhZ50cGg==", "files": [ "lib/dotnet/System.Linq.dll", @@ -11634,7 +11318,6 @@ }, "System.Reflection.Extensions/4.0.0": { "type": "package", - "serviceable": true, "sha512": "dbYaZWCyFAu1TGYUqR2n+Q+1casSHPR2vVW0WVNkXpZbrd2BXcZ7cpvpu9C98CTHtNmyfMWCLpCclDqly23t6A==", "files": [ "lib/DNXCore50/System.Reflection.Extensions.dll", @@ -11682,7 +11365,6 @@ }, "System.Reflection.Primitives/4.0.0": { "type": "package", - "serviceable": true, "sha512": "n9S0XpKv2ruc17FSnaiX6nV47VfHTZ1wLjKZlAirUZCvDQCH71mVp+Ohabn0xXLh5pK2PKp45HCxkqu5Fxn/lA==", "files": [ "lib/DNXCore50/System.Reflection.Primitives.dll", @@ -11716,7 +11398,6 @@ }, "System.Resources.ResourceManager/4.0.0": { "type": "package", - "serviceable": true, "sha512": "qmqeZ4BJgjfU+G2JbrZt4Dk1LsMxO4t+f/9HarNY6w8pBgweO6jT+cknUH7c3qIrGvyUqraBhU45Eo6UtA0fAw==", "files": [ "lib/DNXCore50/System.Resources.ResourceManager.dll", @@ -12061,75 +11742,70 @@ }, "projectFileDependencyGroups": { "": [ + "EntityFramework.Commands >= 7.0.0-rc1-*", "EntityFramework.Core >= 7.0.0-rc1-*", + "EntityFramework.MicrosoftSqlServer >= 7.0.0-rc1-*", "EntityFramework.Relational >= 7.0.0-rc1-*", - "EntityFramework.Commands >= 7.0.0-rc1-*", "EntityFramework.Sqlite >= 7.0.0-rc1-*", - "EntityFramework.MicrosoftSqlServer >= 7.0.0-rc1-*", "EntityFramework7.Npgsql >= 3.1.0-*", "EntityFramework7.Npgsql.Design >= 3.1.0-*", + "Google.Apis.Core >= 1.11.1", + "Google.Apis >= 1.11.1", + "MailKit >= 1.3.0-beta7", + "MarkdownDeep-av.NET >= 1.5.2", "Microsoft.AspNet.Authentication.Cookies >= 1.0.0-rc1-*", + "Microsoft.AspNet.Authentication.Facebook >= 1.0.0-rc1-final", + "Microsoft.AspNet.Authentication.Twitter >= 1.0.0-rc1-final", + "Microsoft.AspNet.Authorization >= 1.0.0-rc1-final", "Microsoft.AspNet.Diagnostics.Entity >= 7.0.0-rc1-*", + "Microsoft.AspNet.Http.Abstractions >= 1.0.0-rc1-final", "Microsoft.AspNet.Identity.EntityFramework >= 3.0.0-rc1-*", "Microsoft.AspNet.IISPlatformHandler >= 1.0.0-rc1-*", + "Microsoft.AspNet.Localization >= 1.0.0-rc1-final", "Microsoft.AspNet.Mvc >= 6.0.0-rc1-*", "Microsoft.AspNet.Mvc.TagHelpers >= 6.0.0-rc1-*", + "Microsoft.AspNet.Owin >= 1.0.0-rc1-final", "Microsoft.AspNet.Server.Kestrel >= 1.0.0-rc1-final", + "Microsoft.AspNet.SignalR.Owin >= 1.2.2", + "Microsoft.AspNet.SignalR.Core >= 2.2.0", + "Microsoft.AspNet.Server.WebListener >= 1.0.0-rc1-final", "Microsoft.AspNet.StaticFiles >= 1.0.0-rc1-*", + "Microsoft.AspNet.SignalR.JS >= 2.2.0", "Microsoft.AspNet.Tooling.Razor >= 1.0.0-rc1-*", + "Microsoft.AspNet.WebSockets.Server >= 1.0.0-rc1-final", + "Microsoft.AspNet.Authentication.OpenIdConnect >= 1.0.0-rc1-final", + "Microsoft.Extensions.Configuration.Abstractions >= 1.0.0-rc1-final", "Microsoft.Extensions.Configuration.FileProviderExtensions >= 1.0.0-rc1-*", "Microsoft.Extensions.Configuration.Json >= 1.0.0-rc1-*", - "Microsoft.Extensions.Configuration.Abstractions >= 1.0.0-rc1-final", "Microsoft.Extensions.Configuration.UserSecrets >= 1.0.0-rc1-*", "Microsoft.Extensions.Logging >= 1.0.0-rc1-final", "Microsoft.Extensions.Logging.Console >= 1.0.0-rc1-final", "Microsoft.Extensions.Logging.Debug >= 1.0.0-rc1-final", - "Microsoft.Framework.DependencyInjection >= 1.0.0-beta8", "Microsoft.Extensions.DependencyInjection.Abstractions >= 1.0.0-rc1-final", - "Microsoft.AspNet.Authentication.Facebook >= 1.0.0-rc1-final", - "Microsoft.AspNet.Authentication.Twitter >= 1.0.0-rc1-final", + "Microsoft.Extensions.Globalization.CultureInfoCache >= 1.0.0-rc1-final", "Microsoft.Extensions.Localization >= 1.0.0-rc1-final", "Microsoft.Extensions.Localization.Abstractions >= 1.0.0-rc1-final", - "Microsoft.Extensions.Globalization.CultureInfoCache >= 1.0.0-rc1-final", - "Microsoft.AspNet.Localization >= 1.0.0-rc1-final", "Microsoft.Framework.ConfigurationModel.Json >= 1.0.0-beta4", - "MarkdownDeep-av.NET >= 1.5.2", + "Microsoft.Framework.DependencyInjection >= 1.0.0-beta8", "Microsoft.Extensions.CodeGeneration >= 1.0.0-rc1-final", "Microsoft.Extensions.PlatformAbstractions >= 1.0.0-rc1-final", "Microsoft.Extensions.CodeGenerators.Mvc >= 1.0.0-rc1-final", "Microsoft.AspNet.Session >= 1.0.0-rc1-final", "Microsoft.NETCore.Platforms >= 1.0.1-beta-23516", - "Microsoft.AspNet.SignalR.JS >= 2.2.0", - "Microsoft.AspNet.WebSockets.Server >= 1.0.0-rc1-final", - "Microsoft.AspNet.Http.Abstractions >= 1.0.0-rc1-final", - "Microsoft.AspNet.SignalR.Owin >= 1.2.2", - "Microsoft.AspNet.Owin >= 1.0.0-rc1-final", - "Microsoft.AspNet.SignalR.Core >= 2.2.0", - "Microsoft.AspNet.Server.WebListener >= 1.0.0-rc1-final", - "Microsoft.AspNetCore.Authentication.OpenIdConnect >= 0.0.1-alpha", - "Microsoft.AspNetCore.Authentication.Cookies >= 0.0.1-alpha", - "Microsoft.AspNet.Authentication.OpenIdConnect >= 1.0.0-rc1-final", - "MailKit >= 1.3.0-beta7", "Microsoft.Framework.Configuration.Abstractions >= 1.0.0-beta8", "Microsoft.Framework.Configuration.Json >= 1.0.0-beta8", "Microsoft.Framework.DependencyInjection.Abstractions >= 1.0.0-beta8", "Microsoft.Framework.Configuration.Binder >= 1.0.0-beta8", "Microsoft.AspNet.Web.Optimization >= 1.1.3", - "PayPalCoreSDK >= 1.7.1", "Microsoft.Extensions.WebEncoders.Core >= 1.0.0-rc1-final", "Microsoft.AspNetCore.Authentication.OAuth >= 0.0.1-alpha", "Microsoft.Extensions.Options >= 0.0.1-alpha", "Microsoft.Extensions.WebEncoders >= 1.0.0-rc1-final", - "Google.Apis.Core >= 1.11.1", - "Google.Apis >= 1.11.1", - "PayPalButtonManagerSDK >= 2.10.109", "Microsoft.AspNet.DataProtection >= 1.0.0-rc1-final", "Microsoft.AspNet.DataProtection.SystemWeb >= 1.0.0-rc1-final", "Microsoft.AspNet.Authentication.JwtBearer >= 1.0.0-rc1-final", - "System.IdentityModel.Tokens >= 5.0.0-rc1-211161024", - "System.IdentityModel.Tokens.Jwt >= 5.0.0-rc1-211161024", - "Microsoft.AspNet.Authorization >= 1.0.0-rc1-final", - "AspNet.Security.OpenIdConnect.Server >= 1.0.0-beta4" + "PayPalCoreSDK >= 1.7.1", + "PayPalButtonManagerSDK >= 2.10.109" ], "DNX,Version=v4.5.1": [] } diff --git a/Yavsc/src/Controllers/OAuthController.cs b/Yavsc/src/Controllers/OAuthController.cs deleted file mode 100644 index 51dc88f8..00000000 --- a/Yavsc/src/Controllers/OAuthController.cs +++ /dev/null @@ -1,424 +0,0 @@ -using System; -using System.Linq; -using System.Security.Claims; -using System.Threading; -using System.Threading.Tasks; -using AspNet.Security.OpenIdConnect.Extensions; -using AspNet.Security.OpenIdConnect.Server; -using Microsoft.AspNet.Authentication; -using Microsoft.AspNet.Authorization; -using Microsoft.AspNet.Builder; -using Microsoft.AspNet.DataProtection.KeyManagement; -using Microsoft.AspNet.Http.Authentication; -using Microsoft.AspNet.Identity; -using Microsoft.AspNet.Mvc; -using Microsoft.Data.Entity; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.OptionsModel; -using Microsoft.IdentityModel.Protocols.OpenIdConnect; -using Yavsc.Extensions; -using Yavsc.Models; -using Yavsc.ViewModels.Account; - -namespace Yavsc.Controllers -{ - [AllowAnonymous] - public class OAuthController : Controller - { - ApplicationDbContext _context; - UserManager _userManager; - - SiteSettings _siteSettings; - - ILogger _logger; - private readonly SignInManager _signInManager; - private TokenAuthOptions _tokenOptions; - - public OAuthController(ApplicationDbContext context, SignInManager signInManager, IKeyManager keyManager, - IOptions tokenOptions, - UserManager userManager, - IOptions siteSettings, - ILoggerFactory loggerFactory - ) - { - _siteSettings = siteSettings.Value; - _context = context; - _signInManager = signInManager; - _tokenOptions = tokenOptions.Value; - _userManager = userManager; - _logger = loggerFactory.CreateLogger(); - } - - - [HttpGet("~/signin")] - public ActionResult SignIn(string returnUrl = null) - { - _logger.LogWarning($"Singin wanted: returnUrl: {returnUrl} "); - // Note: the "returnUrl" parameter corresponds to the endpoint the user agent - // will be redirected to after a successful authentication and not - // the redirect_uri of the requesting client application. - return View("SignIn", new LoginViewModel - { - ReturnUrl = returnUrl, - ExternalProviders = HttpContext.GetExternalProviders() - }); - /* Note: When using an external login provider, redirect the query : - var properties = _signInManager.ConfigureExternalAuthenticationProperties(OpenIdConnectDefaults.AuthenticationScheme, returnUrl); - return new ChallengeResult(OpenIdConnectDefaults.AuthenticationScheme, properties); - */ - } - - [HttpGet("~/authenticate")] - public ActionResult Authenticate(string returnUrl = null) - { - return SignIn(returnUrl); - } - - [HttpGet("~/forbidden")] - public ActionResult Forbidden(string returnUrl = null) - { - return View(returnUrl); - } - - [HttpPost("~/signin")] - public IActionResult SignIn(string Provider, string ReturnUrl) - { - // Note: the "provider" parameter corresponds to the external - // authentication provider choosen by the user agent. - if (string.IsNullOrEmpty(Provider)) - { - _logger.LogWarning("Provider not specified"); - return HttpBadRequest(); - } - - if (!_signInManager.GetExternalAuthenticationSchemes().Any(x => x.AuthenticationScheme == Provider)) - { - _logger.LogWarning($"Provider not found : {Provider}"); - return HttpBadRequest(); - } - - // Instruct the middleware corresponding to the requested external identity - // provider to redirect the user agent to its own authorization endpoint. - // Note: the authenticationScheme parameter must match the value configured in Startup.cs - - // Note: the "returnUrl" parameter corresponds to the endpoint the user agent - // will be redirected to after a successful authentication and not - // the redirect_uri of the requesting client application. - if (string.IsNullOrEmpty(ReturnUrl)) - { - _logger.LogWarning("ReturnUrl not specified"); - return HttpBadRequest(); - } - var redirectUrl = Url.Action("ExternalLoginCallback", "Account", new { ReturnUrl = ReturnUrl }); - var properties = _signInManager.ConfigureExternalAuthenticationProperties(Provider, redirectUrl); - // var properties = new AuthenticationProperties{RedirectUri=ReturnUrl}; - return new ChallengeResult(Provider,properties); - } - - - - [HttpGet("~/signout"), HttpPost("~/signout")] - public async Task SignOut() - { - // Instruct the cookies middleware to delete the local cookie created - // when the user agent is redirected from the external identity provider - // after a successful authentication flow (e.g Google or Facebook). - - await HttpContext.Authentication.SignOutAsync("ServerCookie"); - } - - - - - [HttpGet("~/api/getclaims"), Produces("application/json")] - - public IActionResult GetClaims() - { - var identity = User.Identity as ClaimsIdentity; - - var claims = from c in identity.Claims - select new - { - subject = c.Subject.Name, - type = c.Type, - value = c.Value - }; - - return Ok(claims); - } - - - [HttpGet("~/connect/authorize"), HttpPost("~/connect/authorize")] - public async Task Authorize(CancellationToken cancellationToken) - { - // Note: when a fatal error occurs during the request processing, an OpenID Connect response - // is prematurely forged and added to the ASP.NET context by OpenIdConnectServerHandler. - // You can safely remove this part and let ASOS automatically handle the unrecoverable errors - // by switching ApplicationCanDisplayErrors to false in Startup.cs. - var response = HttpContext.GetOpenIdConnectResponse(); - if (response == null) - { - _logger.LogError("GetOpenIdConnectResponse is null"); - return View("OidcError", response); - } - - // Extract the authorization request from the ASP.NET environment. - var request = HttpContext.GetOpenIdConnectRequest(); - if (request == null) - { - _logger.LogError("An internal error has occurred, GetOpenIdConnectRequest is null"); - return View("OidcError", new OpenIdConnectMessage - { - Error = OpenIdConnectConstants.Errors.ServerError, - ErrorDescription = "An internal error has occurred" - }); - } - - // Note: authentication could be theorically enforced at the filter level via AuthorizeAttribute - // but this authorization endpoint accepts both GET and POST requests while the cookie middleware - // only uses 302 responses to redirect the user agent to the login page, making it incompatible with POST. - // To work around this limitation, the OpenID Connect request is automatically saved in the cache and will be - // restored by the OpenID Connect server middleware after the external authentication process has been completed. - - if (!User.Identities.Any(identity => identity.IsAuthenticated)) - { - return new ChallengeResult(new AuthenticationProperties { - RedirectUri = Url.Action(nameof(Authorize), request.BuildRedirectUrl())}); - } - // Note: ASOS automatically ensures that an application corresponds to the client_id specified - // in the authorization request by calling IOpenIdConnectServerProvider.ValidateAuthorizationRequest. - // In theory, this null check shouldn't be needed, but a race condition could occur if you - // manually removed the application details from the database after the initial check made by ASOS. - /* FIXME response.ClientId && request.ClientId are null or empty here */ - _logger.LogInformation($"ensures that an application corresponds to the client_id specified ({request.ClientId})"); - var application = await GetApplicationAsync(request.ClientId, cancellationToken); - if (application == null) - { - _logger.LogError("Details concerning the calling client application cannot be found in the database"); - return View("OidcError", new OpenIdConnectMessage - { - Error = OpenIdConnectConstants.Errors.InvalidClient, - ErrorDescription = "Details concerning the calling client application cannot be found in the database" - }); - } - - // Note: in a real world application, you'd probably prefer creating a specific view model. - return View("Authorize", new AuthorisationView { Message = request, - Application = application}); - } - - [HttpPost("~/connect/authorize/accept"),Authorize] - public async Task Accept(CancellationToken cancellationToken) - { - var request = HttpContext.GetOpenIdConnectRequest(); - if (request == null) - { - return View("OidcError", new OpenIdConnectMessage - { - Error = OpenIdConnectConstants.Errors.ServerError, - ErrorDescription = "An internal error has occurred" - }); - } - - // Create a new ClaimsIdentity containing the claims that - // will be used to create an id_token, a token or a code. - var identity = new ClaimsIdentity(OpenIdConnectServerDefaults.AuthenticationScheme); - - identity.AddClaim(new Claim(ClaimTypes.NameIdentifier,"name",User.GetUserId())); - if (User.IsInRole(Constants.AdminGroupName)) - identity.AddClaim(new Claim(ClaimTypes.Actor,"role",Constants.AdminGroupName)); - - // Copy the claims retrieved from the external identity provider - // (e.g Google, Facebook, a WS-Fed provider or another OIDC server). - foreach (var claim in User.Claims) - { - // Allow ClaimTypes.Name to be added in the id_token. - // ClaimTypes.NameIdentifier is automatically added, even if its - // destination is not defined or doesn't include "id_token". - // The other claims won't be visible for the client application. - - if (claim.Type == ClaimTypes.Role - || claim.Type == ClaimTypes.Email - || claim.Type == ClaimTypes.NameIdentifier ) { - claim.WithDestination( "code" ); - claim.WithDestination( "id_token" ); - claim.WithDestination( "token" ); - } - - identity.AddClaim(claim); - } - - var application = await GetApplicationAsync(request.ClientId, cancellationToken); - if (application == null) - { - return View("OidcError", new OpenIdConnectMessage - { - Error = OpenIdConnectConstants.Errors.InvalidClient, - ErrorDescription = "Details concerning the calling client application cannot be found in the database" - }); - } - // Create a new ClaimsIdentity containing the claims associated with the application. - // Note: setting identity.Actor is not mandatory but can be useful to access - // the whole delegation chain from the resource server (see ResourceController.cs). - identity.Actor = new ClaimsIdentity(OpenIdConnectServerDefaults.AuthenticationScheme); - identity.Actor.AddClaim(ClaimTypes.NameIdentifier, application.ApplicationID); - identity.Actor.AddClaim(ClaimTypes.Name, application.DisplayName); - - var properties = new AuthenticationProperties(); - - // Note: you can change the list of scopes granted - // to the client application using SetScopes: - properties.SetScopes(new[] { - /* openid: */ OpenIdConnectConstants.Scopes.OpenId, - /* email: */ OpenIdConnectConstants.Scopes.Email, - /* profile: */ OpenIdConnectConstants.Scopes.Profile, - /* api-resource-controller: */ "api-resource-controller" - }); - - // You can also limit the resources endpoints - // the access token should be issued for: - properties.SetResources(new[] { - _siteSettings.Audience - }); - // This call will instruct AspNet.Security.OpenIdConnect.Server to serialize - // the specified identity to build appropriate tokens (id_token and token). - // Note: you should always make sure the identities you return contain either - // a 'sub' or a 'ClaimTypes.NameIdentifier' claim. In this case, the returned - // identities always contain the name identifier returned by the external provider. - // Note: the authenticationScheme parameter must match the value configured in Startup.cs. - await HttpContext.Authentication.SignInAsync( - "oidc-server", - new ClaimsPrincipal(identity), properties); - _logger.LogInformation($"request.GrantType: {request.GrantType}"); - _logger.LogInformation($"request.Code: {request.Code}"); - if (request.GrantType == "authorisation_code") { - var reduri=request.BuildRedirectUrl(); - _logger.LogInformation($"{reduri}"); - return Redirect(reduri); - } - if (request.GrantType == "token") { - - } - return new EmptyResult(); - // return new EmptyResult(); - // Create a new authentication ticket holding the user identity. - /*var ticket = new AuthenticationTicket( - new ClaimsPrincipal(identity), - new AuthenticationProperties(), - OpenIdConnectServerDefaults.AuthenticationScheme);*/ - - // Set the list of scopes granted to the client application. - // Note: this sample always grants the "openid", "email" and "profile" scopes - // when they are requested by the client application: a real world application - // would probably display a form allowing to select the scopes to grant. - /* ticket.SetScopes(new[] { - OpenIdConnectConstants.Scopes.OpenId, - OpenIdConnectConstants.Scopes.Email, - OpenIdConnectConstants.Scopes.Profile, - OpenIdConnectConstants.Scopes.OfflineAccess - }.Intersect(request.GetScopes())); */ - - // Set the resources servers the access token should be issued for. - // ticket.SetResources(new string[]{"resource_server"}); - - //var response = HttpContext.GetOpenIdConnectResponse(); - - - - } - - [HttpPost("~/connect/authorize/deny"), ValidateAntiForgeryToken] - public IActionResult Deny(CancellationToken cancellationToken) - { - var request = HttpContext.GetOpenIdConnectRequest(); - if (request == null) - { - return View("OidcError", new OpenIdConnectMessage - { - Error = OpenIdConnectConstants.Errors.ServerError, - ErrorDescription = "An internal error has occurred" - }); - } - - - // Notify AspNet.Security.OpenIdConnect.Server that the authorization grant has been denied. - // Note: OpenIdConnectServerHandler will automatically take care of redirecting - // the user agent to the client application using the appropriate response_mode. - HttpContext.SetOpenIdConnectResponse(new OpenIdConnectMessage - { - Error = "access_denied", - ErrorDescription = "The authorization grant has been denied by the resource owner", - RedirectUri = request.RedirectUri, - State = request.State - }); - - return new EmptyResult(); - } - - [HttpGet("~/connect/logout")] - public async Task Logout() - { - var response = HttpContext.GetOpenIdConnectResponse(); - if (response != null) - { - _logger.LogError("GetOpenIdConnectResponse is null"); - return View("OidcError", response); - } - - // When invoked, the logout endpoint might receive an unauthenticated request if the server cookie has expired. - // When the client application sends an id_token_hint parameter, the corresponding identity can be retrieved - // using AuthenticateAsync or using User when the authorization server is declared as AuthenticationMode.Active. - var identity = await HttpContext.Authentication.AuthenticateAsync(OpenIdConnectServerDefaults.AuthenticationScheme); - - var request = HttpContext.GetOpenIdConnectRequest(); - if (request == null) - { - _logger.LogError("An internal error has occurred"); - return View("OidcError", new OpenIdConnectMessage - { - Error = OpenIdConnectConstants.Errors.ServerError, - ErrorDescription = "An internal error has occurred" - }); - } - - return View("Logout", Tuple.Create(request, identity)); - } - - [HttpPost("~/connect/logout")] - [ValidateAntiForgeryToken] - public async Task Logout(CancellationToken cancellationToken) - { - // Instruct the cookies middleware to delete the local cookie created - // when the user agent is redirected from the external identity provider - // after a successful authentication flow (e.g Google or Facebook). - await HttpContext.Authentication.SignOutAsync("ServerCookie"); - - // This call will instruct AspNet.Security.OpenIdConnect.Server to serialize - // the specified identity to build appropriate tokens (id_token and token). - // Note: you should always make sure the identities you return contain either - // a 'sub' or a 'ClaimTypes.NameIdentifier' claim. In this case, the returned - // identities always contain the name identifier returned by the external provider. - await HttpContext.Authentication.SignOutAsync(OpenIdConnectServerDefaults.AuthenticationScheme); - } - - protected virtual Task GetApplicationAsync(string identifier, CancellationToken cancellationToken) - { - // Retrieve the application details corresponding to the requested client_id. - return (from application in _context.Applications - where application.ApplicationID == identifier - select application).SingleOrDefaultAsync(cancellationToken); - } - - private IActionResult RedirectToLocal(string returnUrl) - { - if (Url.IsLocalUrl(returnUrl)) - { - return Redirect(returnUrl); - } - else - { - return RedirectToAction(nameof(HomeController.Index), "Home"); - } - } - } -} \ No newline at end of file diff --git a/Yavsc/src/Providers/OAuthProvider.cs b/Yavsc/src/Providers/OAuthProvider.cs deleted file mode 100644 index 7b26fc8f..00000000 --- a/Yavsc/src/Providers/OAuthProvider.cs +++ /dev/null @@ -1,150 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Security.Claims; -using System.Threading.Tasks; -using AspNet.Security.OpenIdConnect.Extensions; -using AspNet.Security.OpenIdConnect.Server; -using Microsoft.AspNet.Identity; -using Microsoft.Data.Entity; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; -using Yavsc.Auth; -using Yavsc.Models; - -namespace Yavsc.Providers { - public sealed class AuthorizationProvider : OpenIdConnectServerProvider { - - private ILogger _logger; - UserTokenProvider tokenProvider; - UserManager userManager; - - SignInManager signInManager; - - public AuthorizationProvider(ILoggerFactory loggerFactory, UserTokenProvider tokenProvider) { - _logger = loggerFactory.CreateLogger(); - this.tokenProvider = tokenProvider; - } - public override Task MatchEndpoint(MatchEndpointContext context) { - // Note: by default, OpenIdConnectServerHandler only handles authorization requests made to the authorization endpoint. - // This context handler uses a more relaxed policy that allows extracting authorization requests received at - // /connect/authorize/accept and /connect/authorize/deny (see AuthorizationController.cs for more information). - if (context.Options.AuthorizationEndpointPath.HasValue && - context.Request.Path.StartsWithSegments(context.Options.AuthorizationEndpointPath)) { - context.MatchesAuthorizationEndpoint(); - } - - return Task.FromResult(null); - } - - public override async Task ValidateAuthorizationRequest(ValidateAuthorizationRequestContext context) { - // Note: the OpenID Connect server middleware supports the authorization code, implicit and hybrid flows - // but this authorization provider only accepts response_type=code authorization/authentication requests. - // You may consider relaxing it to support the implicit or hybrid flows. In this case, consider adding - // checks rejecting implicit/hybrid authorization requests when the client is a confidential application. - if (!context.Request.IsAuthorizationCodeFlow()) { - context.Rejected( - error: OpenIdConnectConstants.Errors.UnsupportedResponseType, - description: "Only the authorization code flow is supported by this authorization server"); - - return; - } - - var database = context.HttpContext.RequestServices.GetRequiredService(); - _logger.LogInformation($"Searching fo app id {context.Request.ClientId}"); - - // Retrieve the application details corresponding to the requested client_id. - var application = await (from entity in database.Applications - where entity.ApplicationID == context.Request.ClientId - select entity).SingleOrDefaultAsync(context.HttpContext.RequestAborted); - - if (application == null) { - context.Rejected( - error: OpenIdConnectConstants.Errors.InvalidClient, - description: "Application not found in the database: ensure that your client_id is correct"); - - return; - } - - if (!string.IsNullOrEmpty(context.Request.RedirectUri) && - !string.Equals(context.Request.RedirectUri, application.RedirectUri, StringComparison.Ordinal)) { - context.Rejected( - error: OpenIdConnectConstants.Errors.InvalidClient, - description: "Invalid redirect_uri"); - - return; - } - _logger.LogInformation("do Validate Authorization!"); - context.Validated(); - } - - public override async Task ValidateTokenRequest(ValidateTokenRequestContext context) { - // Note: the OpenID Connect server middleware supports authorization code, refresh token, client credentials - // and resource owner password credentials grant types but this authorization provider uses a safer policy - // rejecting the last two ones. You may consider relaxing it to support the ROPC or client credentials grant types. - if (!context.Request.IsAuthorizationCodeGrantType() && !context.Request.IsRefreshTokenGrantType()) { - context.Rejected( - error: OpenIdConnectConstants.Errors.UnsupportedGrantType, - description: "Only authorization code and refresh token grant types " + - "are accepted by this authorization server"); - - return; - } - - // Note: client authentication is not mandatory for non-confidential client applications like mobile apps - // (except when using the client credentials grant type) but this authorization server uses a safer policy - // that makes client authentication mandatory and returns an error if client_id or client_secret is missing. - // You may consider relaxing it to support the resource owner password credentials grant type - // with JavaScript or desktop applications, where client credentials cannot be safely stored. - // In this case, call context.Skip() to inform the server middleware the client is not trusted. - if (string.IsNullOrEmpty(context.Request.ClientId) || string.IsNullOrEmpty(context.Request.ClientSecret)) { - context.Rejected( - error: OpenIdConnectConstants.Errors.InvalidRequest, - description: "Missing credentials: ensure that your credentials were correctly " + - "flowed in the request body or in the authorization header"); - - return; - } - - var database = context.HttpContext.RequestServices.GetRequiredService(); - - // Retrieve the application details corresponding to the requested client_id. - var application = await (from entity in database.Applications - where entity.ApplicationID == context.ClientId - select entity).SingleOrDefaultAsync(context.HttpContext.RequestAborted); - - if (application == null) { - context.Rejected( - error: OpenIdConnectConstants.Errors.InvalidClient, - description: "Application not found in the database: ensure that your client_id is correct"); - - return; - } - - if (!string.Equals(context.Request.ClientSecret, application.Secret, StringComparison.Ordinal)) { - context.Rejected( - error: OpenIdConnectConstants.Errors.InvalidClient, - description: "Invalid credentials: ensure that you specified a correct client_secret"); - - return; - } - _logger.LogInformation("do Validate Token request!"); - context.Validated(); - } - - public override Task TokenEndpoint (TokenEndpointContext context) - { - _logger.LogWarning($"OIDC success : IsAccessToken: {context.AuthenticationTicket.IsAccessToken()}"); - return Task.FromResult(0); - } - /* - - public override async Task SerializeAccessToken(SerializeAccessTokenContext context) - { - var user = await userManager.FindByIdAsync(context.HttpContext.User.GetUserId()); - context.AccessToken = await tokenProvider.GenerateAsync("id_token",userManager,user); - context.HandleResponse(); - return ; - } */ - } -} \ No newline at end of file diff --git a/external/oauth-aspnet b/external/oauth-aspnet new file mode 160000 index 00000000..3ce8e249 --- /dev/null +++ b/external/oauth-aspnet @@ -0,0 +1 @@ +Subproject commit 3ce8e249032e49263b4d4e4c9009fd13a39f6415 diff --git a/global.json b/global.json index 3e075f83..8d22797c 100644 --- a/global.json +++ b/global.json @@ -1,5 +1,5 @@ { - "projects": [ "Yavsc" ], + "projects": [ "Yavsc", "external/oauth-aspnet" ], "sdk": { "version": "1.0.0-rc1-update2", "runtime": "mono",