Present nonce in id token

This commit is contained in:
LittleSheep 2024-07-28 22:30:51 +08:00
parent 6ef46d984d
commit 7c09138ef7
9 changed files with 51 additions and 32 deletions

View File

@ -3,9 +3,17 @@
<database-model serializer="dbm" dbms="POSTGRES" family-id="POSTGRES" format-version="4.52">
<root id="1">
<DateStyle>mdy</DateStyle>
<IntrospectionStateNumber>10192</IntrospectionStateNumber>
<Grants>1||-9223372036854775808|c|G
1||10|c|G
1||10|C|G
1||10|T|G
4||-9223372036854775808|c|G
4||10|c|G
4||10|C|G
4||10|T|G</Grants>
<IntrospectionStateNumber>10209</IntrospectionStateNumber>
<ServerVersion>16.3</ServerVersion>
<StartupTime>1721488981</StartupTime>
<StartupTime>1722154972</StartupTime>
<TimeZones>true ACDT
true ACSST
false ACST
@ -800,7 +808,7 @@ false Zulu
13474||10|C|G
13474||-9223372036854775808|U|G
13474||10|U|G</Grants>
<IntrospectionStateNumber>10192</IntrospectionStateNumber>
<IntrospectionStateNumber>10209</IntrospectionStateNumber>
<ObjectId>37312</ObjectId>
<OwnerName>postgres</OwnerName>
</database>
@ -4241,8 +4249,8 @@ false Zulu
<schema id="268" parent="2" name="public">
<Comment>standard public schema</Comment>
<Current>1</Current>
<IntrospectionStateNumber>10192</IntrospectionStateNumber>
<LastIntrospectionLocalTimestamp>2024-07-24.08:06:15</LastIntrospectionLocalTimestamp>
<IntrospectionStateNumber>10209</IntrospectionStateNumber>
<LastIntrospectionLocalTimestamp>2024-07-28.12:55:20</LastIntrospectionLocalTimestamp>
<ObjectId>2200</ObjectId>
<StateNumber>523</StateNumber>
<OwnerName>pg_database_owner</OwnerName>

View File

@ -1,2 +1,2 @@
#n:public
!<md> [10192, 0, null, null, -2147483648, -2147483648]
!<md> [10209, 0, null, null, -2147483648, -2147483648]

View File

@ -4,7 +4,10 @@
<option name="autoReloadType" value="ALL" />
</component>
<component name="ChangeListManager">
<list default="true" id="3fefb2c4-b6f9-466b-a523-53352e8d6f95" name="更改" comment=":bug: Fix permissions in groups" />
<list default="true" id="3fefb2c4-b6f9-466b-a523-53352e8d6f95" name="更改" comment=":bug: Fix permissions in groups">
<change beforePath="$PROJECT_DIR$/.idea/dataSources/74bcf3ef-a2b9-435b-b9e5-f32902a33b25.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/dataSources/74bcf3ef-a2b9-435b-b9e5-f32902a33b25.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/dataSources/74bcf3ef-a2b9-435b-b9e5-f32902a33b25/storage_v2/_src_/database/hy_passport.gNOKQQ/schema/public.abK9xQ.meta" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/dataSources/74bcf3ef-a2b9-435b-b9e5-f32902a33b25/storage_v2/_src_/database/hy_passport.gNOKQQ/schema/public.abK9xQ.meta" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />

View File

@ -39,6 +39,7 @@ type AuthTicket struct {
ExpiredAt *time.Time `json:"expired_at"`
AvailableAt *time.Time `json:"available_at"`
LastGrantAt *time.Time `json:"last_grant_at"`
Nonce *string `json:"nonce"`
ClientID *uint `json:"client_id"`
AccountID uint `json:"account_id"`
}

View File

@ -1,10 +1,11 @@
package api
import (
"git.solsynth.dev/hydrogen/passport/pkg/internal/server/exts"
"strings"
"time"
"git.solsynth.dev/hydrogen/passport/pkg/internal/server/exts"
"git.solsynth.dev/hydrogen/passport/pkg/internal/database"
"git.solsynth.dev/hydrogen/passport/pkg/internal/models"
"git.solsynth.dev/hydrogen/passport/pkg/internal/services"
@ -62,6 +63,7 @@ func authorizeThirdClient(c *fiber.Ctx) error {
id := c.Query("client_id")
response := c.Query("response_type")
redirect := c.Query("redirect_uri")
nonce := c.Query("nonce")
scope := c.Query("scope")
if len(scope) <= 0 {
return fiber.NewError(fiber.StatusBadRequest, "invalid request params")
@ -87,6 +89,7 @@ func authorizeThirdClient(c *fiber.Ctx) error {
[]string{"passport", client.Alias},
c.IP(),
c.Get(fiber.HeaderUserAgent),
&nonce,
)
if err != nil {
@ -107,6 +110,7 @@ func authorizeThirdClient(c *fiber.Ctx) error {
[]string{"passport", client.Alias},
c.IP(),
c.Get(fiber.HeaderUserAgent),
&nonce,
)
if err != nil {

View File

@ -22,6 +22,7 @@ type PayloadClaims struct {
// Additonal Stuff
AuthorizedParties string `json:"azp,omitempty"`
Nonce string `json:"nonce,omitempty"`
Type string `json:"typ"`
}
@ -30,7 +31,7 @@ const (
JwtRefreshType = "refresh"
)
func EncodeJwt(id string, typ, sub, sed string, aud []string, exp time.Time, idTokenUser ...models.Account) (string, error) {
func EncodeJwt(id string, typ, sub, sed string, nonce *string, aud []string, exp time.Time, idTokenUser ...models.Account) (string, error) {
var azp string
for _, item := range aud {
if item != InternalTokenAudience {
@ -61,6 +62,10 @@ func EncodeJwt(id string, typ, sub, sed string, aud []string, exp time.Time, idT
claims.Email = user.GetPrimaryEmail().Content
}
if nonce != nil {
claims.Nonce = *nonce
}
tk := jwt.NewWithClaims(jwt.SigningMethodHS512, claims)
return tk.SignedString([]byte(viper.GetString("secret")))

View File

@ -62,8 +62,12 @@ func NewOauthTicket(
user models.Account,
client models.ThirdClient,
claims, audiences []string,
ip, ua string,
ip, ua string, nonce *string,
) (models.AuthTicket, error) {
if nonce != nil && len(*nonce) == 0 {
nonce = nil
}
ticket := models.AuthTicket{
Claims: claims,
Audiences: audiences,
@ -74,6 +78,7 @@ func NewOauthTicket(
RefreshToken: lo.ToPtr(uuid.NewString()),
AvailableAt: lo.ToPtr(time.Now()),
ExpiredAt: lo.ToPtr(time.Now().Add(7 * 24 * time.Hour)),
Nonce: nonce,
ClientID: &client.ID,
AccountID: user.ID,
}

View File

@ -25,11 +25,11 @@ func GetToken(ticket models.AuthTicket) (atk, rtk string, err error) {
sub := strconv.Itoa(int(ticket.AccountID))
sed := strconv.Itoa(int(ticket.ID))
atk, err = EncodeJwt(*ticket.AccessToken, JwtAccessType, sub, sed, ticket.Audiences, time.Now().Add(atkDeadline))
atk, err = EncodeJwt(*ticket.AccessToken, JwtAccessType, sub, sed, nil, ticket.Audiences, time.Now().Add(atkDeadline))
if err != nil {
return
}
rtk, err = EncodeJwt(*ticket.RefreshToken, JwtRefreshType, sub, sed, ticket.Audiences, time.Now().Add(rtkDeadline))
rtk, err = EncodeJwt(*ticket.RefreshToken, JwtRefreshType, sub, sed, nil, ticket.Audiences, time.Now().Add(rtkDeadline))
if err != nil {
return
}
@ -89,7 +89,7 @@ func ExchangeOauthToken(clientId, clientSecret, redirectUri, token string) (idk,
sub := strconv.Itoa(int(ticket.AccountID))
sed := strconv.Itoa(int(ticket.ID))
idk, err = EncodeJwt(*ticket.AccessToken, JwtAccessType, sub, sed, ticket.Audiences, time.Now().Add(24*time.Minute), user)
idk, err = EncodeJwt(*ticket.AccessToken, JwtAccessType, sub, sed, ticket.Nonce, ticket.Audiences, time.Now().Add(24*time.Minute), user)
return
}

View File

@ -107,7 +107,7 @@ const requestedClaims = computed(() => {
const panel = ref("confirm")
async function tryAuthorize() {
const res = await request(`/api/auth/o/authorize${location.search}`, {
const res = await request("/api/auth/o/authorize" + window.location.search, {
headers: { Authorization: `Bearer ${getAtk()}` },
})
@ -139,19 +139,10 @@ function decline() {
async function approve() {
loading.value = true
const res = await request(
"/api/auth/o/authorize?" +
new URLSearchParams({
client_id: route.query["client_id"] as string,
redirect_uri: encodeURIComponent(route.query["redirect_uri"] as string),
response_type: "code",
scope: route.query["scope"] as string,
}),
{
method: "POST",
headers: { Authorization: `Bearer ${getAtk()}` },
},
)
const res = await request("/api/auth/o/authorize" + window.location.search, {
method: "POST",
headers: { Authorization: `Bearer ${getAtk()}` },
})
if (res.status !== 200) {
error.value = await res.text()
@ -169,11 +160,13 @@ function callback(ticket: any) {
}
function getClaimDescription(key: string): ClaimType {
return Object.prototype.hasOwnProperty.call(claims, key) ? claims[key] : {
icon: "mdi-asterisk",
name: key,
description: "Unknown claim...",
}
return Object.prototype.hasOwnProperty.call(claims, key)
? claims[key]
: {
icon: "mdi-asterisk",
name: key,
description: "Unknown claim...",
}
}
</script>