Skip to content

Commit 8b4bac7

Browse files
committed
ClaimsPrincipal gRPC parsing:
* Updated subtree from https://github.com/azure/azure-functions-language-worker-protobug. Branch: dev. Commit: f786ef5. * Updated generate_protos.* build scripts. * Added parsing for ClaimsPrincipal to gRPC, plus tests.
1 parent 3614b3b commit 8b4bac7

File tree

7 files changed

+105
-4
lines changed

7 files changed

+105
-4
lines changed

src/WebJobs.Script.Grpc/WebJobs.Script.Grpc.csproj

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,16 +35,16 @@
3535
<PackageReference Include="System.ComponentModel.Annotations" Version="4.5.0" />
3636
</ItemGroup>
3737

38-
<ItemGroup>
39-
<Folder Include="Messages\DotNet\" />
40-
</ItemGroup>
41-
4238
<ItemGroup>
4339
<Reference Include="Newtonsoft.Json">
4440
<HintPath>C:\Program Files\dotnet\sdk\NuGetFallbackFolder\newtonsoft.json\11.0.2\lib\netstandard2.0\Newtonsoft.Json.dll</HintPath>
4541
</Reference>
4642
</ItemGroup>
4743

44+
<ItemGroup>
45+
<Folder Include="Messages\" />
46+
</ItemGroup>
47+
4848
<Target Name="GenerateProtoFiles" BeforeTargets="BeforeBuild" Inputs="azure-functions-language-worker-protobuf/src/proto/FunctionRpc.proto" Outputs="Messages/DotNet/FunctionRpc.cs;Messages/DotNet/FunctionRpcGrpc.cs">
4949
<Exec Command="./generate_protos.$(Ext)" />
5050
<ItemGroup>

src/WebJobs.Script.Grpc/azure-functions-language-worker-protobuf/src/proto/FunctionRpc.proto

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ option go_package ="github.com/Azure/azure-functions-go-worker/internal/rpc";
1010
package AzureFunctionsRpcMessages;
1111

1212
import "google/protobuf/duration.proto";
13+
import "identity/ClaimsIdentityRpc.proto";
1314

1415
// Interface exported by the server.
1516
service FunctionRpc {
@@ -379,4 +380,5 @@ message RpcHttp {
379380
map<string,string> query = 15;
380381
bool enable_content_negotiation= 16;
381382
TypedData rawBody = 17;
383+
repeated RpcClaimsIdentity identities = 18;
382384
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
syntax = "proto3";
2+
// protobuf vscode extension: https://marketplace.visualstudio.com/items?itemName=zxh404.vscode-proto3
3+
4+
// Light-weight representation of a .NET System.Security.Claims.ClaimsIdentity object.
5+
// This is the same serialization as found in EasyAuth, and needs to be kept in sync with
6+
// its ClaimsIdentitySlim definition, as seen in the WebJobs extension:
7+
// https://github.com/Azure/azure-webjobs-sdk-extensions/blob/dev/src/WebJobs.Extensions.Http/ClaimsIdentitySlim.cs
8+
message RpcClaimsIdentity {
9+
string authentication_type = 1;
10+
string name_claim_type = 2;
11+
string role_claim_type = 3;
12+
repeated RpcClaim claims = 4;
13+
}
14+
15+
// Light-weight representation of a .NET System.Security.Claims.Claim object.
16+
// This is the same serialization as found in EasyAuth, and needs to be kept in sync with
17+
// its ClaimSlim definition, as seen in the WebJobs extension:
18+
// https://github.com/Azure/azure-webjobs-sdk-extensions/blob/dev/src/WebJobs.Extensions.Http/ClaimSlim.cs
19+
message RpcClaim {
20+
string value = 1;
21+
string type = 2;
22+
}

src/WebJobs.Script.Grpc/generate_protos.bat

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ mkdir %MSGDIR%
4646

4747
set OUTDIR=%MSGDIR%\DotNet
4848
mkdir %OUTDIR%
49+
50+
for /D %%D in (%PROTO_PATH%\*) do for %%F in (%%D\*.proto) do %GRPC_TOOLS_PATH%\protoc.exe %%F --csharp_out %OUTDIR% --grpc_out=%OUTDIR% --plugin=protoc-gen-grpc=%GRPC_TOOLS_PATH%\grpc_csharp_plugin.exe --proto_path=%%D --proto_path=%PROTOBUF_TOOLS%
51+
4952
%GRPC_TOOLS_PATH%\protoc.exe %PROTO% --csharp_out %OUTDIR% --grpc_out=%OUTDIR% --plugin=protoc-gen-grpc=%GRPC_TOOLS_PATH%\grpc_csharp_plugin.exe --proto_path=%PROTO_PATH% --proto_path=%PROTOBUF_TOOLS%
5053

5154
@rem add pragma warning disable labels to generated files

src/WebJobs.Script.Grpc/generate_protos.sh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,11 @@ mkdir $MSGDIR
6565

6666
OUTDIR=$MSGDIR/DotNet
6767
mkdir $OUTDIR
68+
69+
for d in $PROTO_PATH/*/*.proto; do
70+
$GRPC_TOOLS_PATH/protoc $f --csharp_out $OUTDIR --grpc_out=$OUTDIR --plugin=protoc-gen-grpc=$GRPC_TOOLS_PATH/grpc_csharp_plugin --proto_path=$PROTO_PATH --proto_path=$PROTOBUF_TOOLS
71+
done
72+
6873
$GRPC_TOOLS_PATH/protoc $PROTO --csharp_out $OUTDIR --grpc_out=$OUTDIR --plugin=protoc-gen-grpc=$GRPC_TOOLS_PATH/grpc_csharp_plugin --proto_path=$PROTO_PATH --proto_path=$PROTOBUF_TOOLS
6974

7075
# add #pragma warning disable labels

src/WebJobs.Script/Rpc/MessageExtensions/RpcMessageConversionExtensions.cs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,29 @@ public static TypedData ToRpc(this object value)
102102
}
103103
}
104104

105+
// parse ClaimsPrincipal if exists
106+
if (request.HttpContext?.User?.Identities != null)
107+
{
108+
foreach (var id in request.HttpContext.User.Identities)
109+
{
110+
// asdf
111+
var rpcId = new RpcClaimsIdentity();
112+
if (id.AuthenticationType != null)
113+
{
114+
rpcId.AuthenticationType = id.AuthenticationType;
115+
}
116+
rpcId.NameClaimType = id.NameClaimType;
117+
rpcId.RoleClaimType = id.RoleClaimType;
118+
119+
foreach (var claim in id.Claims)
120+
{
121+
rpcId.Claims.Add(new RpcClaim { Value = claim.Value, Type = claim.Type });
122+
}
123+
124+
http.Identities.Add(rpcId);
125+
}
126+
}
127+
105128
// parse request body as content-type
106129
if (request.Body != null && request.ContentLength > 0)
107130
{

test/WebJobs.Script.Tests/Rpc/RpcMessageConversionExtensionsTests.cs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
// Licensed under the MIT License. See License.txt in the project root for license information.
33

44
using System.Collections.Generic;
5+
using System.Linq;
6+
using System.Security.Claims;
57
using Microsoft.AspNetCore.Http;
68
using Microsoft.Azure.WebJobs.Script.Description;
79
using Microsoft.Azure.WebJobs.Script.Grpc.Messages;
@@ -85,5 +87,49 @@ public void ToBindingInfo_Defaults_EmptyDataType()
8587
Assert.Equal(bindingInfo.Type, bindingMetadata.Type);
8688
Assert.Equal(bindingInfo.DataType, BindingInfo.Types.DataType.Undefined);
8789
}
90+
91+
[Fact]
92+
public void HttpObjects_ClaimsPrincipal()
93+
{
94+
HttpRequest request = HttpTestHelpers.CreateHttpRequest("GET", $"http://localhost/apihttptrigger-scenarios");
95+
96+
MockEasyAuth(request, "facebook", "Connor McMahon", "10241897674253170");
97+
98+
var rpcRequestObject = request.ToRpc();
99+
var identity = request.HttpContext.User.Identities.ToList().ElementAtOrDefault(0);
100+
var rpcIdentity = rpcRequestObject.Http.Identities.ElementAtOrDefault(0);
101+
Assert.NotNull(identity);
102+
Assert.NotNull(rpcIdentity);
103+
104+
Assert.Equal(rpcIdentity.AuthenticationType, "facebook");
105+
Assert.Equal(rpcIdentity.NameClaimType, "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name");
106+
Assert.Equal(rpcIdentity.RoleClaimType, "http://schemas.microsoft.com/ws/2008/06/identity/claims/role");
107+
108+
var claims = identity.Claims.ToList();
109+
for (int j = 0; j < claims.Count; j++)
110+
{
111+
Assert.True(rpcIdentity.Claims.ElementAtOrDefault(j) != null);
112+
Assert.Equal(rpcIdentity.Claims[j].Type, claims[j].Type);
113+
Assert.Equal(rpcIdentity.Claims[j].Value, claims[j].Value);
114+
}
115+
}
116+
117+
internal static void MockEasyAuth(HttpRequest request, string provider, string name, string id)
118+
{
119+
var claims = new List<Claim>
120+
{
121+
new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name", name),
122+
new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn", name),
123+
new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier", id)
124+
};
125+
126+
var identity = new ClaimsIdentity(
127+
claims,
128+
provider,
129+
"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name",
130+
"http://schemas.microsoft.com/ws/2008/06/identity/claims/role");
131+
132+
request.HttpContext.User = new ClaimsPrincipal(new List<ClaimsIdentity> { identity });
133+
}
88134
}
89135
}

0 commit comments

Comments
 (0)