✨ Present nonce in id token
This commit is contained in:
parent
6ef46d984d
commit
7c09138ef7
@ -3,9 +3,17 @@
|
|||||||
<database-model serializer="dbm" dbms="POSTGRES" family-id="POSTGRES" format-version="4.52">
|
<database-model serializer="dbm" dbms="POSTGRES" family-id="POSTGRES" format-version="4.52">
|
||||||
<root id="1">
|
<root id="1">
|
||||||
<DateStyle>mdy</DateStyle>
|
<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>
|
<ServerVersion>16.3</ServerVersion>
|
||||||
<StartupTime>1721488981</StartupTime>
|
<StartupTime>1722154972</StartupTime>
|
||||||
<TimeZones>true ACDT
|
<TimeZones>true ACDT
|
||||||
true ACSST
|
true ACSST
|
||||||
false ACST
|
false ACST
|
||||||
@ -800,7 +808,7 @@ false Zulu
|
|||||||
13474||10|C|G
|
13474||10|C|G
|
||||||
13474||-9223372036854775808|U|G
|
13474||-9223372036854775808|U|G
|
||||||
13474||10|U|G</Grants>
|
13474||10|U|G</Grants>
|
||||||
<IntrospectionStateNumber>10192</IntrospectionStateNumber>
|
<IntrospectionStateNumber>10209</IntrospectionStateNumber>
|
||||||
<ObjectId>37312</ObjectId>
|
<ObjectId>37312</ObjectId>
|
||||||
<OwnerName>postgres</OwnerName>
|
<OwnerName>postgres</OwnerName>
|
||||||
</database>
|
</database>
|
||||||
@ -4241,8 +4249,8 @@ false Zulu
|
|||||||
<schema id="268" parent="2" name="public">
|
<schema id="268" parent="2" name="public">
|
||||||
<Comment>standard public schema</Comment>
|
<Comment>standard public schema</Comment>
|
||||||
<Current>1</Current>
|
<Current>1</Current>
|
||||||
<IntrospectionStateNumber>10192</IntrospectionStateNumber>
|
<IntrospectionStateNumber>10209</IntrospectionStateNumber>
|
||||||
<LastIntrospectionLocalTimestamp>2024-07-24.08:06:15</LastIntrospectionLocalTimestamp>
|
<LastIntrospectionLocalTimestamp>2024-07-28.12:55:20</LastIntrospectionLocalTimestamp>
|
||||||
<ObjectId>2200</ObjectId>
|
<ObjectId>2200</ObjectId>
|
||||||
<StateNumber>523</StateNumber>
|
<StateNumber>523</StateNumber>
|
||||||
<OwnerName>pg_database_owner</OwnerName>
|
<OwnerName>pg_database_owner</OwnerName>
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
#n:public
|
#n:public
|
||||||
!<md> [10192, 0, null, null, -2147483648, -2147483648]
|
!<md> [10209, 0, null, null, -2147483648, -2147483648]
|
||||||
|
5
.idea/workspace.xml
generated
5
.idea/workspace.xml
generated
@ -4,7 +4,10 @@
|
|||||||
<option name="autoReloadType" value="ALL" />
|
<option name="autoReloadType" value="ALL" />
|
||||||
</component>
|
</component>
|
||||||
<component name="ChangeListManager">
|
<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="SHOW_DIALOG" value="false" />
|
||||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||||
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
||||||
|
@ -39,6 +39,7 @@ type AuthTicket struct {
|
|||||||
ExpiredAt *time.Time `json:"expired_at"`
|
ExpiredAt *time.Time `json:"expired_at"`
|
||||||
AvailableAt *time.Time `json:"available_at"`
|
AvailableAt *time.Time `json:"available_at"`
|
||||||
LastGrantAt *time.Time `json:"last_grant_at"`
|
LastGrantAt *time.Time `json:"last_grant_at"`
|
||||||
|
Nonce *string `json:"nonce"`
|
||||||
ClientID *uint `json:"client_id"`
|
ClientID *uint `json:"client_id"`
|
||||||
AccountID uint `json:"account_id"`
|
AccountID uint `json:"account_id"`
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.solsynth.dev/hydrogen/passport/pkg/internal/server/exts"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"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/database"
|
||||||
"git.solsynth.dev/hydrogen/passport/pkg/internal/models"
|
"git.solsynth.dev/hydrogen/passport/pkg/internal/models"
|
||||||
"git.solsynth.dev/hydrogen/passport/pkg/internal/services"
|
"git.solsynth.dev/hydrogen/passport/pkg/internal/services"
|
||||||
@ -62,6 +63,7 @@ func authorizeThirdClient(c *fiber.Ctx) error {
|
|||||||
id := c.Query("client_id")
|
id := c.Query("client_id")
|
||||||
response := c.Query("response_type")
|
response := c.Query("response_type")
|
||||||
redirect := c.Query("redirect_uri")
|
redirect := c.Query("redirect_uri")
|
||||||
|
nonce := c.Query("nonce")
|
||||||
scope := c.Query("scope")
|
scope := c.Query("scope")
|
||||||
if len(scope) <= 0 {
|
if len(scope) <= 0 {
|
||||||
return fiber.NewError(fiber.StatusBadRequest, "invalid request params")
|
return fiber.NewError(fiber.StatusBadRequest, "invalid request params")
|
||||||
@ -87,6 +89,7 @@ func authorizeThirdClient(c *fiber.Ctx) error {
|
|||||||
[]string{"passport", client.Alias},
|
[]string{"passport", client.Alias},
|
||||||
c.IP(),
|
c.IP(),
|
||||||
c.Get(fiber.HeaderUserAgent),
|
c.Get(fiber.HeaderUserAgent),
|
||||||
|
&nonce,
|
||||||
)
|
)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -107,6 +110,7 @@ func authorizeThirdClient(c *fiber.Ctx) error {
|
|||||||
[]string{"passport", client.Alias},
|
[]string{"passport", client.Alias},
|
||||||
c.IP(),
|
c.IP(),
|
||||||
c.Get(fiber.HeaderUserAgent),
|
c.Get(fiber.HeaderUserAgent),
|
||||||
|
&nonce,
|
||||||
)
|
)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -22,6 +22,7 @@ type PayloadClaims struct {
|
|||||||
|
|
||||||
// Additonal Stuff
|
// Additonal Stuff
|
||||||
AuthorizedParties string `json:"azp,omitempty"`
|
AuthorizedParties string `json:"azp,omitempty"`
|
||||||
|
Nonce string `json:"nonce,omitempty"`
|
||||||
Type string `json:"typ"`
|
Type string `json:"typ"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,7 +31,7 @@ const (
|
|||||||
JwtRefreshType = "refresh"
|
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
|
var azp string
|
||||||
for _, item := range aud {
|
for _, item := range aud {
|
||||||
if item != InternalTokenAudience {
|
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
|
claims.Email = user.GetPrimaryEmail().Content
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if nonce != nil {
|
||||||
|
claims.Nonce = *nonce
|
||||||
|
}
|
||||||
|
|
||||||
tk := jwt.NewWithClaims(jwt.SigningMethodHS512, claims)
|
tk := jwt.NewWithClaims(jwt.SigningMethodHS512, claims)
|
||||||
|
|
||||||
return tk.SignedString([]byte(viper.GetString("secret")))
|
return tk.SignedString([]byte(viper.GetString("secret")))
|
||||||
|
@ -62,8 +62,12 @@ func NewOauthTicket(
|
|||||||
user models.Account,
|
user models.Account,
|
||||||
client models.ThirdClient,
|
client models.ThirdClient,
|
||||||
claims, audiences []string,
|
claims, audiences []string,
|
||||||
ip, ua string,
|
ip, ua string, nonce *string,
|
||||||
) (models.AuthTicket, error) {
|
) (models.AuthTicket, error) {
|
||||||
|
if nonce != nil && len(*nonce) == 0 {
|
||||||
|
nonce = nil
|
||||||
|
}
|
||||||
|
|
||||||
ticket := models.AuthTicket{
|
ticket := models.AuthTicket{
|
||||||
Claims: claims,
|
Claims: claims,
|
||||||
Audiences: audiences,
|
Audiences: audiences,
|
||||||
@ -74,6 +78,7 @@ func NewOauthTicket(
|
|||||||
RefreshToken: lo.ToPtr(uuid.NewString()),
|
RefreshToken: lo.ToPtr(uuid.NewString()),
|
||||||
AvailableAt: lo.ToPtr(time.Now()),
|
AvailableAt: lo.ToPtr(time.Now()),
|
||||||
ExpiredAt: lo.ToPtr(time.Now().Add(7 * 24 * time.Hour)),
|
ExpiredAt: lo.ToPtr(time.Now().Add(7 * 24 * time.Hour)),
|
||||||
|
Nonce: nonce,
|
||||||
ClientID: &client.ID,
|
ClientID: &client.ID,
|
||||||
AccountID: user.ID,
|
AccountID: user.ID,
|
||||||
}
|
}
|
||||||
|
@ -25,11 +25,11 @@ func GetToken(ticket models.AuthTicket) (atk, rtk string, err error) {
|
|||||||
|
|
||||||
sub := strconv.Itoa(int(ticket.AccountID))
|
sub := strconv.Itoa(int(ticket.AccountID))
|
||||||
sed := strconv.Itoa(int(ticket.ID))
|
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 {
|
if err != nil {
|
||||||
return
|
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 {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -89,7 +89,7 @@ func ExchangeOauthToken(clientId, clientSecret, redirectUri, token string) (idk,
|
|||||||
|
|
||||||
sub := strconv.Itoa(int(ticket.AccountID))
|
sub := strconv.Itoa(int(ticket.AccountID))
|
||||||
sed := strconv.Itoa(int(ticket.ID))
|
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
|
return
|
||||||
}
|
}
|
||||||
|
@ -107,7 +107,7 @@ const requestedClaims = computed(() => {
|
|||||||
const panel = ref("confirm")
|
const panel = ref("confirm")
|
||||||
|
|
||||||
async function tryAuthorize() {
|
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()}` },
|
headers: { Authorization: `Bearer ${getAtk()}` },
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -139,19 +139,10 @@ function decline() {
|
|||||||
|
|
||||||
async function approve() {
|
async function approve() {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
const res = await request(
|
const res = await request("/api/auth/o/authorize" + window.location.search, {
|
||||||
"/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",
|
method: "POST",
|
||||||
headers: { Authorization: `Bearer ${getAtk()}` },
|
headers: { Authorization: `Bearer ${getAtk()}` },
|
||||||
},
|
})
|
||||||
)
|
|
||||||
|
|
||||||
if (res.status !== 200) {
|
if (res.status !== 200) {
|
||||||
error.value = await res.text()
|
error.value = await res.text()
|
||||||
@ -169,7 +160,9 @@ function callback(ticket: any) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getClaimDescription(key: string): ClaimType {
|
function getClaimDescription(key: string): ClaimType {
|
||||||
return Object.prototype.hasOwnProperty.call(claims, key) ? claims[key] : {
|
return Object.prototype.hasOwnProperty.call(claims, key)
|
||||||
|
? claims[key]
|
||||||
|
: {
|
||||||
icon: "mdi-asterisk",
|
icon: "mdi-asterisk",
|
||||||
name: key,
|
name: key,
|
||||||
description: "Unknown claim...",
|
description: "Unknown claim...",
|
||||||
|
Loading…
Reference in New Issue
Block a user