From 54563e41435957691c7b414b0ec1c3d4bd48a3d6 Mon Sep 17 00:00:00 2001 From: "d.breimaier" Date: Mon, 27 Feb 2023 09:12:32 +0100 Subject: [PATCH] BasicAuthentication --- .../App_Start/AddAuthTokenHeaderParamete.vb | 41 ----------- .../App_Start/BasicAuthenticationAttribute.vb | 47 +++++++++++++ VERAG_REST_SERVER/App_Start/SwaggerConfig.vb | 43 ++++++++---- VERAG_REST_SERVER/App_Start/WebApiConfig.vb | 12 +++- .../BasicAuthentificationHandler.vb | 68 +++++++++++++++++++ .../V1/AvisoController/AVISOController.vb | 5 +- VERAG_REST_SERVER/Global.asax.vb | 2 + VERAG_REST_SERVER/IService/IUserService.vb | 5 ++ VERAG_REST_SERVER/Service/Service.vb | 7 ++ VERAG_REST_SERVER/VERAG_REST_SERVER.vbproj | 59 +++++++++++++++- VERAG_REST_SERVER/packages.config | 15 ++++ 11 files changed, 242 insertions(+), 62 deletions(-) delete mode 100644 VERAG_REST_SERVER/App_Start/AddAuthTokenHeaderParamete.vb create mode 100644 VERAG_REST_SERVER/App_Start/BasicAuthenticationAttribute.vb create mode 100644 VERAG_REST_SERVER/BasicAuthentificationHandler.vb create mode 100644 VERAG_REST_SERVER/IService/IUserService.vb create mode 100644 VERAG_REST_SERVER/Service/Service.vb diff --git a/VERAG_REST_SERVER/App_Start/AddAuthTokenHeaderParamete.vb b/VERAG_REST_SERVER/App_Start/AddAuthTokenHeaderParamete.vb deleted file mode 100644 index 9cc5cfc..0000000 --- a/VERAG_REST_SERVER/App_Start/AddAuthTokenHeaderParamete.vb +++ /dev/null @@ -1,41 +0,0 @@ -'Imports System.Web.Http.Description -'Imports System.Web.Http.Filters -'Imports Microsoft.AspNetCore.Authorization -'Imports Swashbuckle.Swagger - -'Public Class AddAuthTokenHeaderParameter -' Implements IOperationFilter - -' Public Sub Apply(operation As Operation, schemaRegistry As SchemaRegistry, apiDescription As ApiDescription) Implements IOperationFilter.Apply - -' Dim filterPipeline = apiDescription.ActionDescriptor.GetFilterPipeline() -' Dim isAuthorized = filterPipeline.Select(Function(s) s.Instance).Any(Function(sc) sc.GetType().Equals(GetType(IAuthorizationFilter))) - -' Dim allowAnonymous = apiDescription.ActionDescriptor.GetCustomAttributes(Of AllowAnonymousAttribute)().Any() - -' If isAuthorized And (Not allowAnonymous) Then -' If operation.parameters Is Nothing Then -' operation.parameters = New List(Of Parameter) -' End If -' operation.parameters.Add(New Parameter With { -' .name = "Authorization", -' .in = "header", -' .description = "access token", -' .required = True, -' .type = "string", -' .[default] = "Bearer " -' }) -' End If - -' End Sub - - - - - -'End Class - - - - - diff --git a/VERAG_REST_SERVER/App_Start/BasicAuthenticationAttribute.vb b/VERAG_REST_SERVER/App_Start/BasicAuthenticationAttribute.vb new file mode 100644 index 0000000..cdbf520 --- /dev/null +++ b/VERAG_REST_SERVER/App_Start/BasicAuthenticationAttribute.vb @@ -0,0 +1,47 @@ +Imports System.Net +Imports System.Net.Http +Imports System.Security.Principal +Imports System.Threading +Imports System.Web.Http.Controllers +Imports System.Web.Http.Description +Imports System.Web.Http.Filters +Imports Microsoft.AspNetCore.Authorization +Imports Swashbuckle.Swagger + +Public Class BasicAuthenticationAttribute + Inherits AuthorizationFilterAttribute + + Public Overrides Sub OnAuthorization(ByVal actionContext As HttpActionContext) + Dim authHeader = actionContext.Request.Headers.Authorization + + If authHeader IsNot Nothing Then + Dim authenticationToken = actionContext.Request.Headers.Authorization.Parameter + Dim decodedAuthenticationToken = Encoding.UTF8.GetString(Convert.FromBase64String(authenticationToken)) + Dim usernamePasswordArray = decodedAuthenticationToken.Split(":"c) + Dim userName = usernamePasswordArray(0) + Dim password = usernamePasswordArray(1) + Dim isValid = userName = "test" AndAlso password = "password" + + If isValid Then + Dim principal = New GenericPrincipal(New GenericIdentity(userName), Nothing) + Thread.CurrentPrincipal = principal + actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.OK, "User " & userName & " successfully authenticated") + Return + End If + End If + + HandleUnathorized(actionContext) + End Sub + + Private Shared Sub HandleUnathorized(ByVal actionContext As HttpActionContext) + actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized) + actionContext.Response.Headers.Add("WWW-Authenticate", "Basic Scheme='Data' location = 'http://localhost:") + End Sub +End Class + + + + + + + diff --git a/VERAG_REST_SERVER/App_Start/SwaggerConfig.vb b/VERAG_REST_SERVER/App_Start/SwaggerConfig.vb index 9a6a33f..2055c95 100644 --- a/VERAG_REST_SERVER/App_Start/SwaggerConfig.vb +++ b/VERAG_REST_SERVER/App_Start/SwaggerConfig.vb @@ -1,4 +1,5 @@ -Imports System.Web.Http +Imports System.Net.Http +Imports System.Web.Http Imports System.Web.Http.Description Imports Microsoft.Extensions.Options Imports Swashbuckle.Application @@ -6,6 +7,7 @@ Imports Swashbuckle.Swagger Imports Swashbuckle.SwaggerUi + ' @@ -21,43 +23,56 @@ Public Class SwaggerConfig GlobalConfiguration.Configuration.EnableSwagger(Function(c) 'c.SingleApiVersion("v1", descr) - c.PrettyPrint() c.MultipleApiVersions(Function(apiDesc, targetApiVersion) ResolveVersionSupportByRouteConstraint(apiDesc, targetApiVersion), Function(vc) - vc.Version("v1", descr & " V1") + vc.Version("v1", descr & " V1").Description("A sample API for testing ").TermsOfService("Some Terms").Contact(Function(cont) + cont.Name("VERAG AG") + cont.Url("http://test.at") + cont.Email("Mail.test") + End Function).License(Function(lic) + lic.Name("Lizenz") + lic.Url("http://test.at") + End Function) + + vc.Version("v2", descr & " V2") vc.Version("v3", descr & " V3") End Function) - 'c.OAuth2("oauth2").Description("OAuth2 Implicit Grant").Flow("implicit").AuthorizationUrl("http://petstore.swagger.wordnik.com/api/oauth/dialog").Scopes(Function(scopes) - ' scopes.Add("read", "Read access to protected resources") - ' scopes.Add("write", "Write access to protected resources") - ' End Function) - 'c.BasicAuth("basic").Description("Basic HTTP Authentication") + ' c.OAuth2("oauth2").Description("OAuth2 Implicit Grant").Flow("implicit").AuthorizationUrl("http://petstore.swagger.wordnik.com/api/oauth/dialog").Scopes(Function(scopes) + 'End Function) + c.BasicAuth("basic").Description("Basic HTTP Authentication") + 'c.ApiKey("apiKey").Description("API Key Authentication").Name("apiKey").In("header") - c.OperationFilter(Of AddAuthorizationHeaderParameterOperationFilter)() - 'c.OperationFilter(Of AddAuthTokenHeaderParameter)() + + 'c.OperationFilter(Of AddAuthorizationHeaderParameterOperationFilter)() + + 'c.OperationFilter(Of BasicAuthenticationAttribute)() 'c.IncludeXmlComments($"{AppDomain.CurrentDomain.BaseDirectory}\bin\MyApi.XML") - 'c.RootUrl(Function(req) "http://localhost:58452/") + 'c.RootUrl(Function(req) req.GetRouteData) End Function).EnableSwaggerUi(Function(c) c.DocumentTitle(descr) + c.EnableDiscoveryUrlSelector() c.DocExpansion(DocExpansion.Full) - c.EnableApiKeySupport("apiKey", "header") - - 'c.EnableOAuth2Support(clientId:="test-client-id", clientSecret:=Nothing, realm:="test-realm", appName:="Swagger UI", additionalQueryStringParams:=New Dictionary(Of String, String)() From { + 'c.EnableApiKeySupport("apiKey", "header") + 'c.CustomAsset("index", yourAssembly, "YourWebApiProject.SwaggerExtensions.index.html") + 'c.EnableOAuth2Support(clientId:="test-client-id", clientSecret:=Nothing, realm:="test-realm", appName:="Swagger UI") + 'additionalQueryStringParams:=New Dictionary(Of String, String)() From { ' {"foo", "bar"} '}) End Function) + + End Sub diff --git a/VERAG_REST_SERVER/App_Start/WebApiConfig.vb b/VERAG_REST_SERVER/App_Start/WebApiConfig.vb index 269a958..d772268 100644 --- a/VERAG_REST_SERVER/App_Start/WebApiConfig.vb +++ b/VERAG_REST_SERVER/App_Start/WebApiConfig.vb @@ -8,6 +8,8 @@ Imports Microsoft.Extensions.DependencyInjection Imports Microsoft.Web.Http Imports Microsoft.Web.Http.Routing Imports Microsoft.Web.Http.Versioning +Imports Swashbuckle.Application +Imports Swashbuckle.Swagger Public Module WebApiConfig @@ -58,8 +60,12 @@ Public Module WebApiConfig Dim constraintsResolver = New DefaultInlineConstraintResolver() constraintsResolver.ConstraintMap.Add("apiVersion", GetType(ApiVersionRouteConstraint)) + + config.MapHttpAttributeRoutes(constraintsResolver) - config.Filters.Add(New AuthorizeAttribute) 'wenn alle API Aufrufe autorisiert werden müssen! + 'config.Filters.Add(New AuthorizeAttribute) 'wenn alle API Aufrufe autorisiert werden müssen/ansonsten können einzelene Controlleraufrufe auth. werden! + config.Filters.Add(New BasicAuthenticationAttribute()) + config.AddApiVersioning(Function(options) @@ -77,8 +83,12 @@ Public Module WebApiConfig c.SubstituteApiVersionInUrl = True End Function) + + SwaggerConfig.Register(config) + + End Sub diff --git a/VERAG_REST_SERVER/BasicAuthentificationHandler.vb b/VERAG_REST_SERVER/BasicAuthentificationHandler.vb new file mode 100644 index 0000000..56e5028 --- /dev/null +++ b/VERAG_REST_SERVER/BasicAuthentificationHandler.vb @@ -0,0 +1,68 @@ +Imports System.Net.Http.Headers +Imports System.Security.Claims +Imports System.Text.Encodings.Web +Imports System.Threading.Tasks +Imports Microsoft.AspNetCore.Authentication +Imports Microsoft.Extensions.Logging +Imports Microsoft.Extensions.Options +Imports Microsoft.AspNetCore.Http.Abstractions + + +Public Class BasicAuthentificationHandler + Inherits AuthenticationHandler(Of AuthenticationSchemeOptions) + + ReadOnly _userService As IUserService + + + Public Sub New(userService As IUserService, options As Microsoft.Extensions.Options.IOptionsMonitor(Of AuthenticationSchemeOptions), logger As ILoggerFactory, encoder As UrlEncoder, clock As ISystemClock) + + MyBase.New(options, logger, encoder, clock) + _userService = userService + + + End Sub + + Protected Overrides Function HandleChallengeAsync(properties As AuthenticationProperties) As Task + GetResponse().Headers("WWW-Authenticate") = "Basic" + Return MyBase.HandleChallengeAsync(properties) + End Function + + Private Function GetResponse() As Object + Return Response + End Function + + Protected Overrides Function HandleAuthenticateAsync() As Task(Of AuthenticateResult) + + Dim username As String = "" + + Try + + Dim authHeader = AuthenticationHeaderValue.Parse(GetResponse().Headers("Authorization")) + Dim credentials = Encoding.UTF8.GetString(Convert.FromBase64String(authHeader.Parameter)).Split(":") + username = credentials.FirstOrDefault + Dim password = credentials.LastOrDefault + + If Not _userService.CheckUser(username, password) Then + Throw New NotImplementedException("Invalid Username or password") + End If + + + + Catch ex As Exception + + Return Task.FromResult(AuthenticateResult.Fail(ex.Message)) + + End Try + + Dim claims = {New Claim(ClaimTypes.Name, username)} + Dim idendity = New ClaimsIdentity(claims, Scheme.Name) + Dim principal = New ClaimsPrincipal(idendity) + Dim ticket = New AuthenticationTicket(principal, Scheme.Name) + + Return Task.FromResult(AuthenticateResult.Success(ticket)) + + + + + End Function +End Class diff --git a/VERAG_REST_SERVER/Controllers/V1/AvisoController/AVISOController.vb b/VERAG_REST_SERVER/Controllers/V1/AvisoController/AVISOController.vb index 85e32eb..2959855 100644 --- a/VERAG_REST_SERVER/Controllers/V1/AvisoController/AVISOController.vb +++ b/VERAG_REST_SERVER/Controllers/V1/AvisoController/AVISOController.vb @@ -3,11 +3,10 @@ Imports System.Web.Http Imports Microsoft.Web.Http Namespace ApiController.Controllers - 'v{version:apiVersion} - + Public Class AVISOController Inherits System.Web.Http.ApiController @@ -30,7 +29,7 @@ Namespace ApiController.Controllers Public Function GetValue() As String - Return "Hello world! -> muss autorisiert werden!" + Return "Hello world!" End Function Public Function PostValue(ByVal API_AVISO As VERAG_PROG_ALLGEMEIN.cVERAG_in_TRAviso) As String diff --git a/VERAG_REST_SERVER/Global.asax.vb b/VERAG_REST_SERVER/Global.asax.vb index 3792458..1279355 100644 --- a/VERAG_REST_SERVER/Global.asax.vb +++ b/VERAG_REST_SERVER/Global.asax.vb @@ -6,7 +6,9 @@ Public Class WebApiApplication Protected Sub Application_Start() GlobalConfiguration.Configure(AddressOf WebApiConfig.Register) + End Sub + End Class diff --git a/VERAG_REST_SERVER/IService/IUserService.vb b/VERAG_REST_SERVER/IService/IUserService.vb new file mode 100644 index 0000000..5d4c789 --- /dev/null +++ b/VERAG_REST_SERVER/IService/IUserService.vb @@ -0,0 +1,5 @@ +Public Interface IUserService + + Function CheckUser(ByVal username As String, ByVal passowrd As String) + +End Interface diff --git a/VERAG_REST_SERVER/Service/Service.vb b/VERAG_REST_SERVER/Service/Service.vb new file mode 100644 index 0000000..ef2cfb9 --- /dev/null +++ b/VERAG_REST_SERVER/Service/Service.vb @@ -0,0 +1,7 @@ +Public Class Service + Implements IUserService + + Public Function CheckUser(username As String, passowrd As String) As Object Implements IUserService.CheckUser + Return username.Equals("testuser") & passowrd.Equals("pwd") + End Function +End Class diff --git a/VERAG_REST_SERVER/VERAG_REST_SERVER.vbproj b/VERAG_REST_SERVER/VERAG_REST_SERVER.vbproj index 9539126..8e12b9e 100644 --- a/VERAG_REST_SERVER/VERAG_REST_SERVER.vbproj +++ b/VERAG_REST_SERVER/VERAG_REST_SERVER.vbproj @@ -53,16 +53,31 @@ ..\packages\Microsoft.AspNet.WebApi.Versioning.ApiExplorer.4.1.1\lib\net45\Microsoft.AspNet.WebApi.Versioning.ApiExplorer.dll - + + ..\packages\Microsoft.AspNetCore.Authentication.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Authentication.dll + + False ..\packages\Microsoft.AspNetCore.Authentication.Abstractions.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Authentication.Abstractions.dll ..\packages\Microsoft.AspNetCore.Authorization.7.0.3\lib\net462\Microsoft.AspNetCore.Authorization.dll + + ..\packages\Microsoft.AspNetCore.Cryptography.Internal.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Cryptography.Internal.dll + + + ..\packages\Microsoft.AspNetCore.DataProtection.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.DataProtection.dll + + + ..\packages\Microsoft.AspNetCore.DataProtection.Abstractions.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.DataProtection.Abstractions.dll + ..\packages\Microsoft.AspNetCore.Http.2.2.2\lib\netstandard2.0\Microsoft.AspNetCore.Http.dll + + ..\packages\Microsoft.AspNetCore.Http.Abstractions.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Http.Abstractions.dll + ..\packages\Microsoft.AspNetCore.Http.Features.5.0.17\lib\net461\Microsoft.AspNetCore.Http.Features.dll @@ -136,6 +151,18 @@ ..\packages\Microsoft.Extensions.WebEncoders.7.0.3\lib\net462\Microsoft.Extensions.WebEncoders.dll + + ..\packages\Microsoft.IdentityModel.Abstractions.6.27.0\lib\net461\Microsoft.IdentityModel.Abstractions.dll + + + ..\packages\Microsoft.IdentityModel.JsonWebTokens.6.27.0\lib\net461\Microsoft.IdentityModel.JsonWebTokens.dll + + + ..\packages\Microsoft.IdentityModel.Logging.6.27.0\lib\net461\Microsoft.IdentityModel.Logging.dll + + + ..\packages\Microsoft.IdentityModel.Tokens.6.27.0\lib\net461\Microsoft.IdentityModel.Tokens.dll + ..\packages\Microsoft.Net.Http.Headers.2.2.8\lib\netstandard2.0\Microsoft.Net.Http.Headers.dll @@ -145,6 +172,9 @@ ..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll + + ..\packages\Microsoft.Win32.Registry.4.5.0\lib\net461\Microsoft.Win32.Registry.dll + ..\packages\Newtonsoft.Json.13.0.2\lib\net45\Newtonsoft.Json.dll @@ -160,16 +190,21 @@ + ..\packages\System.Diagnostics.DiagnosticSource.7.0.1\lib\net462\System.Diagnostics.DiagnosticSource.dll + + ..\packages\System.IdentityModel.Tokens.Jwt.6.27.0\lib\net461\System.IdentityModel.Tokens.Jwt.dll + ..\packages\System.IO.Pipelines.7.0.0\lib\net462\System.IO.Pipelines.dll ..\packages\System.Memory.4.5.5\lib\net461\System.Memory.dll + ..\packages\Microsoft.AspNet.WebApi.Client.5.2.9\lib\net45\System.Net.Http.Formatting.dll @@ -187,6 +222,20 @@ True True + + + ..\packages\System.Security.AccessControl.4.5.0\lib\net461\System.Security.AccessControl.dll + + + ..\packages\System.Security.Cryptography.Xml.4.5.0\lib\net461\System.Security.Cryptography.Xml.dll + + + ..\packages\System.Security.Permissions.4.5.0\lib\net461\System.Security.Permissions.dll + + + ..\packages\System.Security.Principal.Windows.4.5.0\lib\net461\System.Security.Principal.Windows.dll + + ..\packages\System.Text.Encodings.Web.7.0.0\lib\net462\System.Text.Encodings.Web.dll @@ -196,6 +245,7 @@ ..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll + ..\packages\System.ValueTuple.4.5.0\lib\net47\System.ValueTuple.dll @@ -254,10 +304,11 @@ - + + @@ -270,6 +321,7 @@ Global.asax + @@ -291,6 +343,7 @@ Settings.settings True + @@ -359,7 +412,7 @@ True 58452 / - http://localhost:58452/ + http://localhost:58452 False False diff --git a/VERAG_REST_SERVER/packages.config b/VERAG_REST_SERVER/packages.config index 28aba7a..95d990a 100644 --- a/VERAG_REST_SERVER/packages.config +++ b/VERAG_REST_SERVER/packages.config @@ -9,10 +9,14 @@ + + + + @@ -42,20 +46,31 @@ + + + + + + + + + + +