Skip to content

Commit

Permalink
(OAuth2):将OAuth2的选项配置到OSharpOptions中,添加GitHub账号登录的支持
Browse files Browse the repository at this point in the history
  • Loading branch information
gmf520 committed Mar 31, 2019
1 parent 85993ca commit 51b99a2
Show file tree
Hide file tree
Showing 22 changed files with 201 additions and 73 deletions.
32 changes: 32 additions & 0 deletions src/OSharp/Core/Options/OAuth2Options.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// -----------------------------------------------------------------------
// <copyright file="OAuth2Options.cs" company="OSharp开源团队">
// Copyright (c) 2014-2019 OSharp. All rights reserved.
// </copyright>
// <site>http://www.osharp.org</site>
// <last-editor>郭明锋</last-editor>
// <last-date>2019-03-31 18:18</last-date>
// -----------------------------------------------------------------------

namespace OSharp.Core.Options
{
/// <summary>
/// 第三方OAuth2登录的配置选项
/// </summary>
public class OAuth2Options
{
/// <summary>
/// 获取或设置 本应用在第三方OAuth2系统中的客户端Id
/// </summary>
public string ClientId { get; set; }

/// <summary>
/// 获取或设置 本应用在第三方OAuth2系统中的客户端密钥
/// </summary>
public string ClientSecret { get; set; }

/// <summary>
/// 获取或设置 是否启用
/// </summary>
public bool Enabled { get; set; }
}
}
6 changes: 6 additions & 0 deletions src/OSharp/Core/Options/OSharpOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,19 @@ public class OsharpOptions
public OsharpOptions()
{
DbContexts = new ConcurrentDictionary<string, OsharpDbContextOptions>(StringComparer.OrdinalIgnoreCase);
OAuth2S = new ConcurrentDictionary<string, OAuth2Options>();
}

/// <summary>
/// 获取 数据上下文配置信息
/// </summary>
public IDictionary<string, OsharpDbContextOptions> DbContexts { get; }

/// <summary>
/// 获取 第三方OAuth2登录配置信息
/// </summary>
public IDictionary<string, OAuth2Options> OAuth2S { get; }

/// <summary>
/// 获取或设置 邮件发送选项
/// </summary>
Expand Down
14 changes: 13 additions & 1 deletion src/OSharp/Core/Options/OSharpOptionsSetup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,20 @@ public void Configure(OsharpOptions options)
{
SetDbContextOptionses(options);

IConfigurationSection section;
//OAuth2
section = _configuration.GetSection("OSharp:OAuth2");
IDictionary<string, OAuth2Options> dict = section.Get<Dictionary<string, OAuth2Options>>();
if (dict != null)
{
foreach (KeyValuePair<string, OAuth2Options> item in dict)
{
options.OAuth2S.Add(item.Key, item.Value);
}
}

//MailSender
IConfigurationSection section = _configuration.GetSection("OSharp:MailSender");
section = _configuration.GetSection("OSharp:MailSender");
MailSenderOptions sender = section.Get<MailSenderOptions>();
if (sender != null)
{
Expand Down
77 changes: 44 additions & 33 deletions tests/web/Liuliu.Demo.Core/Identity/IdentityPack.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
// -----------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Threading.Tasks;
Expand All @@ -23,6 +24,7 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.IdentityModel.Tokens;

using OSharp.Core.Options;
using OSharp.Exceptions;
using OSharp.Extensions;
using OSharp.Identity;
Expand Down Expand Up @@ -104,16 +106,16 @@ protected override void AddAuthentication(IServiceCollection services)
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(jwt =>
{
string secret = configuration["Authentication:Jwt:Secret"];
string secret = configuration["OSharp:Jwt:Secret"];
if (secret.IsNullOrEmpty())
{
throw new OsharpException("配置文件中Authentication配置的Jwt节点的Secret不能为空");
throw new OsharpException("配置文件中OSharp配置的Jwt节点的Secret不能为空");
}

jwt.TokenValidationParameters = new TokenValidationParameters()
{
ValidIssuer = configuration["Authentication:Jwt:Issuer"]?? "osharp identity",
ValidAudience = configuration["Authentication:Jwt:Audience"]?? "osharp client",
ValidIssuer = configuration["OSharp:Jwt:Issuer"] ?? "osharp identity",
ValidAudience = configuration["OSharp:Jwt:Audience"] ?? "osharp client",
IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(secret)),
LifetimeValidator = (before, expires, token, param) => expires > DateTime.Now,
ValidateLifetime = true
Expand All @@ -138,44 +140,53 @@ protected override void AddAuthentication(IServiceCollection services)
};
});

bool enabled = configuration["Authentication:QQ:Enabled"].CastTo(false);
if (enabled)
// OAuth2
IConfigurationSection section = configuration.GetSection("OSharp:OAuth2");
IDictionary<string, OAuth2Options> dict = section.Get<Dictionary<string, OAuth2Options>>();
if (dict == null)
{
string appId = configuration["Authentication:QQ:AppId"];
if (string.IsNullOrEmpty(appId))
return;
}
foreach (KeyValuePair<string, OAuth2Options> pair in dict)
{
OAuth2Options value = pair.Value;
if (!value.Enabled)
{
throw new OsharpException("配置文件中Authentication配置的QQ节点的AppId不能为空");
continue;
}
string appKey = configuration["Authentication:QQ:AppKey"];
if (string.IsNullOrEmpty(appKey))
if (string.IsNullOrEmpty(value.ClientId))
{
throw new OsharpException("配置文件中Authentication配置的QQ节点的AppKey不能为空");
throw new OsharpException($"配置文件中OSharp:OAuth2配置的{pair.Key}节点的ClientId不能为空");
}
authenticationBuilder.AddQQ(qq =>
{
qq.AppId = appId;
qq.AppKey = appKey;
});
}

enabled = configuration["Authentication:Microsoft:Enabled"].CastTo(false);
if (enabled)
{
string clientId = configuration["Authentication:Microsoft:ClientId"];
if (string.IsNullOrEmpty(clientId))
if (string.IsNullOrEmpty(value.ClientSecret))
{
throw new OsharpException("配置文件中Authentication配置的Microsoft节点的ClientId不能为空");
throw new OsharpException($"配置文件中OSharp:OAuth2配置的{pair.Key}节点的ClientSecret不能为空");
}
string clientSecret = configuration["Authentication:Microsoft:ClientSecret"];
if (string.IsNullOrEmpty(clientSecret))

switch (pair.Key)
{
throw new OsharpException("配置文件中Authentication配置的Microsoft节点的ClientSecret不能为空");
case "QQ":
authenticationBuilder.AddQQ(opts =>
{
opts.AppId = value.ClientId;
opts.AppKey = value.ClientSecret;
});
break;
case "Microsoft":
authenticationBuilder.AddMicrosoftAccount(opts =>
{
opts.ClientId = value.ClientId;
opts.ClientSecret = value.ClientSecret;
});
break;
case "GitHub":
authenticationBuilder.AddGitHub(opts =>
{
opts.ClientId = value.ClientId;
opts.ClientSecret = value.ClientSecret;
});
break;
}
authenticationBuilder.AddMicrosoftAccount(ms =>
{
ms.ClientId = clientId;
ms.ClientSecret = clientSecret;
});
}
}

Expand Down
1 change: 1 addition & 0 deletions tests/web/Liuliu.Demo.Core/Liuliu.Demo.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
<Import Project="../../../build/public.props" />
<Import Project="../../../build/version.props" />
<ItemGroup>
<PackageReference Include="Authentication.GitHub.Core" Version="1.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.MicrosoftAccount" Version="2.2.0" />
</ItemGroup>

Expand Down
47 changes: 27 additions & 20 deletions tests/web/Liuliu.Demo.Web/appsettings.Development.json
Original file line number Diff line number Diff line change
@@ -1,24 +1,4 @@
{
//"ConnectionStrings": {
// "DefaultDbContext": "Server=.;Database=osharpns.demo.webapi3;Trusted_Connection=True;MultipleActiveResultSets=true"
//},
"Authentication": {
"Jwt": {
"Issuer": "osharp identity",
"Audience": "osharp angular demo",
"Secret": "{8619F7C3-B53C-4B85-99F0-983D351ECD82}"
},
"QQ": {
"AppId": "你的QQ互联项目AppId",
"AppKey": "你的QQ互联项目AppKey",
"Enabled": false
},
"Microsoft": {
"ClientId": "你的微软项目ClientId",
"ClientSecret": "你的微软项目ClientSecret",
"Enabled": false
}
},
"Logging": {
"IncludeScopes": true,
"LogLevel": {
Expand Down Expand Up @@ -67,6 +47,33 @@
// "AutoMigrationEnabled": true
//}
},
"OAuth2": {
//"QQ": {
// "ClientId": "你的QQ互联项目AppId",
// "ClientSecret": "你的QQ互联项目AppKey",
// "Enabled": false
//},
//"Microsoft": {
// "ClientId": "你的微软项目ClientId",
// "ClientSecret": "你的微软项目ClientSecret",
// "Enabled": false
//},
//"GitHub": {
// "ClientId": "你的微软项目ClientId",
// "ClientSecret": "你的微软项目ClientSecret",
// "Enabled": false
//}
},
"Logging": {
"IncludeScopes": true,
"LogLevel": {
"Default": "Debug",
"System": "Information",
"Microsoft": "Warning",
"OSharp": "Debug",
"Liuliu": "Debug"
}
},
"MailSender": {
"Host": "smtp.66soft.net",
"DisplayName": "柳柳发件测试",
Expand Down
3 changes: 0 additions & 3 deletions tests/web/Liuliu.Demo.Web/appsettings.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
{
"ConnectionStrings": {
"DefaultDbContext": "Server=.;Database=osharp.demo.webapi;User Id=test;Password=abcd123456;MultipleActiveResultSets=true"
},
"Logging": {
"IncludeScopes": true,
"LogLevel": {
Expand Down
2 changes: 1 addition & 1 deletion tests/web/ui/ng-alain7/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion tests/web/ui/ng-alain7/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "osharpns",
"version": "0.4.7",
"version": "0.5.0-beta01",
"scripts": {
"ng": "ng",
"start": "npm run color-less && ng serve -o --port 4201 --proxy-config proxy.config.json",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Component, Inject, ChangeDetectionStrategy } from '@angular/core';
import { Router } from '@angular/router';
import { SettingsService } from '@delon/theme';
import { DA_SERVICE_TOKEN, ITokenService } from '@delon/auth';
import { IdentityService } from '@shared/osharp/services/identity.service';

@Component({
selector: 'header-user',
Expand Down Expand Up @@ -34,11 +35,14 @@ export class HeaderUserComponent {
constructor(
public settings: SettingsService,
private router: Router,
private identity: IdentityService,
@Inject(DA_SERVICE_TOKEN) private tokenService: ITokenService,
) { }

logout() {
this.tokenService.clear();
this.router.navigateByUrl(this.tokenService.login_url);
this.identity.logout().then(res => {
this.tokenService.clear();
this.router.navigateByUrl(this.tokenService.login_url);
});
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<div class="alain-default__header-logo">
<a [routerLink]="['/']" class="alain-default__header-logo-link">
<img class="alain-default__header-logo-expanded" src="./assets/logo-full.svg" alt="{{settings.app.name}}" style="max-height:40px;" />
<img class="alain-default__header-logo-collapsed" src="./assets/logo.svg" alt="{{settings.app.name}}" style="max-height:30px;" />
<img class="alain-default__header-logo-expanded" src="./assets/osharp/logo-full.svg" alt="{{settings.app.name}}" style="max-height:40px;" />
<img class="alain-default__header-logo-collapsed" src="./assets/osharp/logo.svg" alt="{{settings.app.name}}" style="max-height:30px;" />
</a>
</div>
<div class="alain-default__nav-wrap">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
<div class="wrap">
<div class="top">
<div class="head">
<img class="logo" src="./assets/logo-color.svg">
<a href="/"><span class="title">ng-alain</span></a>
<img class="logo" src="./assets/osharp/logo-color.svg">
<a href="/"><span class="title">osharp</span></a>
</div>
<div class="desc">武林中最有影响力的《葵花宝典》;欲练神功,挥刀自宫</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ import { Exception500Component } from './500.component';
import { ExceptionTriggerComponent } from './trigger.component';

const routes: Routes = [
{ path: '403', component: Exception403Component },
{ path: '404', component: Exception404Component },
{ path: '500', component: Exception500Component },
{ path: '403', component: Exception403Component, data: { title: '403' } },
{ path: '404', component: Exception404Component, data: { title: '404' } },
{ path: '500', component: Exception500Component, data: { title: '500' } },
{ path: 'trigger', component: ExceptionTriggerComponent },
];

@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
})
export class ExceptionRoutingModule {}
export class ExceptionRoutingModule { }
Original file line number Diff line number Diff line change
Expand Up @@ -81,5 +81,6 @@
{{ 'app.login.sign-in-with' | translate }}
<i nz-icon type="qq" nz-tooltip="使用QQ登录" theme="outline" class="icon" (click)="open('QQ')"></i>
<i nz-icon type="windows" nz-tooltip="使用Microsoft Account登录" theme="outline" class="icon" (click)="open('Microsoft')"></i>
<i nz-icon type="github" nz-tooltip="使用GitHub登录" theme="outline" class="icon" (click)="open('GitHub')"></i>
<a class="register" routerLink="/passport/register" acl="Root.Site.Identity.Register">{{ 'app.login.signup' | translate }}</a>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export class ProfileEditComponent implements OnInit {

ngOnInit() {
let user = this.settings.user;
let userNameEdit = ['QQ_', 'Microsoft_'].some(m => user.name.startsWith(m));
let userNameEdit = ['QQ_', 'Microsoft_', 'GitHub_'].some(m => user.name.startsWith(m));
this.headImgUrl = user.avatar;
this.schema = {
properties: {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<div nz-col nzXs="24" nzSm="20" nzMd="16">
<button nz-button (click)="st.reload()">刷新</button>
<st #st [data]="url" [columns]="columns" [req]="req" [res]="res"></st>
<st #st [data]="readUrl" [columns]="columns" [req]="req" [res]="res"></st>
</div>
3 changes: 2 additions & 1 deletion tests/web/ui/ng-alain7/src/app/routes/routes.routing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,13 @@ import { DashboardComponent } from './dashboard/dashboard.component';
// single pages
import { CallbackComponent } from './callback/callback.component';
import { ACLGuard } from '@delon/acl';
import { SimpleGuard } from '@delon/auth';

const routes: Routes = [
{
path: '',
component: LayoutDefaultComponent,
canActivate: [],
canActivate: [SimpleGuard],
data: { title: '主页' },
children: [
{ path: '', redirectTo: 'dashboard', pathMatch: 'full' },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export class ModalTreeComponent {

constructor(public http: _HttpClient, private alain: AlainService) { }

private loadTreeData() {
loadTreeData() {
let url = this.treeDataUrl;
if (!url) {
return;
Expand Down
Loading

0 comments on commit 51b99a2

Please sign in to comment.