添加StartUp类
Imports System.Web.Http
Imports Owin
Imports Microsoft.Owin
Imports Microsoft.Owin.Security.OAuth
Imports System.Web.Http.Cors
Imports System.Threading.Tasks
Imports System.Security.Claims
Imports Microsoft.Owin.Security.Infrastructure
Imports Microsoft.Owin.Security
Imports System.Collections.Concurrent
<Assembly: OwinStartup(GetType(StartUp))>
Public Class StartUp
Public Sub Configuration(ByVal app As IAppBuilder)
Dim config As HttpConfiguration = New HttpConfiguration()
'EnableCorsAttribute 在命名空间 System.Web.Http.Cors 中(在新安装 的 Microsoft.AspNet.Cors 内)
'而其中的参数,表示对可跨域调用的方法的配置(这里全为 "*" 表示所有方法均可跨域调用)
'但是有的时候在跨域配置完成后,任然不能在其他项目进行跨域调用。这有可能是浏览器不支持的原因
'好在 JQuery 提供了简单的方法,只需要通过 JQ 设置 :jQuery.support.cors = true
config.EnableCors(New EnableCorsAttribute("*", "*", "*"))
ConfigureOAuth(app)
WebApiConfig.Register(config)
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll)
app.UseWebApi(config)
End Sub
Public Sub ConfigureOAuth(ByVal app As IAppBuilder)
Dim OAuthServerOptions As OAuthAuthorizationServerOptions = New OAuthAuthorizationServerOptions() With {
.AllowInsecureHttp = True,
.TokenEndpointPath = New PathString("/token"),
.AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
.Provider = New SimpleAuthorizationServerProvider(),
.RefreshTokenProvider = New RefreshTokenProvider()
}
app.UseOAuthAuthorizationServer(OAuthServerOptions)
app.UseOAuthBearerAuthentication(New OAuthBearerAuthenticationOptions())
End Sub
End Class
Public Class SimpleAuthorizationServerProvider
Inherits OAuthAuthorizationServerProvider
'grant_type参数:
'简化模式implicit
'授权码模式grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb
'密码模式 grant_type=password&username=johndoe&password=A3ddj3w
'客户端模式(client credentials)
'更新令牌 grant_type=refresh_token&refresh_token=tGzv3JOkF0XG5Qx2TlKWIA access_token只能刷新一次,下次失败!
Public Overrides Async Function ValidateClientAuthentication(ByVal context As OAuthValidateClientAuthenticationContext) As Task
Await Task.Factory.StartNew(Function() context.Validated())
End Function
Public Overrides Async Function GrantResourceOwnerCredentials(ByVal context As OAuthGrantResourceOwnerCredentialsContext) As Task
Await Task.Factory.StartNew(Sub() context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", {"*"}))
dim User as new User with {.UserName=xxxx} '此应在数据库在查询
If IsNothing(user) Then
context.SetError("invalid_grant", "用户名或密码是否正确,webapi权限是否为允许")
Return
End If
Dim identity = New ClaimsIdentity(context.Options.AuthenticationType)
identity.AddClaim(New Claim("sign", context.UserName))
identity.AddClaim(New Claim("role", "user"))
context.Validated(identity)
End Function
'刷新令牌保存
Public Overrides Async Function GrantRefreshToken(ByVal context As OAuthGrantRefreshTokenContext) As Task
Dim newId = New ClaimsIdentity(context.Ticket.Identity)
newId.AddClaim(New Claim("refreshToken", "refreshToken"))
'newId.AddClaim(New Claim("sign", context.Ticket.Identity.Claims("sign").Value))
Dim newTicket = New AuthenticationTicket(newId, context.Ticket.Properties)
context.Validated(newTicket)
Await MyBase.GrantRefreshToken(context)
End Function
''' <summary>
''' 令牌的验证
''' </summary>
''' <param name="context"></param>
''' <returns></returns>
Public Overrides Async Function GrantClientCredentials(ByVal context As OAuthGrantClientCredentialsContext) As Task
Dim oAuthIdentity = New ClaimsIdentity(context.Options.AuthenticationType)
Dim ticket = New AuthenticationTicket(oAuthIdentity, context.Ticket.Properties)
context.Validated(ticket)
End Function
End Class
''' <summary>
''' 刷新令牌生成
''' </summary>
Public Class RefreshTokenProvider
Inherits AuthenticationTokenProvider
Private Shared _refreshTokens As ConcurrentDictionary(Of String, String) = New ConcurrentDictionary(Of String, String)()
Public Overrides Sub Create(ByVal context As AuthenticationTokenCreateContext)
context.Ticket.Properties.IssuedUtc = DateTime.UtcNow
context.Ticket.Properties.ExpiresUtc = DateTime.UtcNow.AddDays(30)
Dim tokenValue As String = Guid.NewGuid().ToString("n")
context.SetToken(tokenValue)
_refreshTokens(tokenValue) = context.SerializeTicket()
End Sub
Public Overrides Sub Receive(ByVal context As AuthenticationTokenReceiveContext)
Dim value As String = String.Empty
If _refreshTokens.TryRemove(context.Token, value) Then
context.DeserializeTicket(value)
End If
End Sub
End Class