问题描述
我已经成功地使用令牌存储JwtTokenStore(JwtAccesstokenStore)来解码详细信息,但是现在它需要使用redis以便撤消令牌。
这是我的代码:
LD_PRELOAD=/some/path ./cmd
和我的customjwtaccesstokenconverter:
cat <<'EOT' > read-eio.c
#define _GNU_SOURCE
#include <unistd.h>
#include <err.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
int main(int ac,char **av){
int fd; char buf[32];
if(ac < 2 || !av[1])
errx(1,"usage: %s cmd args..",av[0]);
if((fd = open("/proc/self/exe",O_PATH)) == -1)
err(1,"open /proc/self/exe");
snprintf(buf,sizeof buf,"/dev/fd/%d",fd);
if(setenv("LD_PRELOAD",buf,1))
err(1,"setenv");
execvp(av[1],av + 1);
err(1,"execvp %s",av[1]);
}
ssize_t read(int fd,void *b,size_t z){
errno = EIO; return -1;
}
EOT
cc -fPIC -pie read-eio.c -o read-eio
###########
$ ./read-eio cat
cat: -: Input/output error
令牌增强器:
@Bean
public TokenStore tokenStore() {
return new RedisTokenStore(redisConnectionFactory);
// return new JwtTokenStore(defaultAccesstokenConverter());
}
@Bean
public JwtAccesstokenConverter defaultAccesstokenConverter() {
JwtAccesstokenConverter converter = new JwtAccesstokenConverter();
converter.setAccesstokenConverter(new CustomJWTAccesstokenConverter());
try {
converter.afterPropertiesSet();
} catch (Exception e) {
e.printstacktrace();
}
converter.setKeyPair(this.keyPair());
return converter;
}
我不知道何时使用redistokenstore。它没有转到CustomJWTAccesstokenConverter,因为当我尝试获取其他信息(decodeDetails)时返回null。
public class CustomJWTAccesstokenConverter extends DefaultAccesstokenConverter {
@Override
public OAuth2Authentication extractAuthentication(Map<String,?> claims) {
OAuth2Authentication authentication
= super.extractAuthentication(claims);
authentication.setDetails(claims);
return authentication;
}
}
解决方法
您还需要配置令牌增强器-
package main
import (
"context"
"errors"
"fmt"
"time"
"github.com/gammazero/workerpool"
)
func main() {
// here define a timeout for 5 sec,// the task should be terminate after 5 sec
ctx,cancel := context.WithTimeout(context.Background(),time.Second*5)
defer cancel()
runner := newRunner(ctx,10)
runner.do(job{
Name: "a",Task: func() jobResult {
select {
case <-ctx.Done():
return jobResult{Error: errors.New("Timedout,exiting")}
default:
myLongRunningFunc("A job")
}
return jobResult{Data: "from a"}
},})
runner.do(job{
Name: "b",Task: func() jobResult {
select {
case <-ctx.Done():
return jobResult{Error: errors.New("Timeouts,exiting")}
default:
myLongRunningFunc("B job")
}
return jobResult{Data: "from b"}
},})
results := runner.getjobResults()
fmt.Println(results)
time.Sleep(time.Second * 60)
}
func myLongRunningFunc(name string) {
for i := 0; i < 100000; i++ {
time.Sleep(time.Second * 1)
msg := "job" + name + " running..\n"
fmt.Println(msg)
}
}
type runner struct {
*workerpool.WorkerPool
ctx context.Context
kill chan struct{}
result chan jobResult
results []jobResult
}
func (r *runner) processResults() {
for {
select {
case res,ok := <-r.result:
if !ok {
goto Done
}
r.results = append(r.results,res)
}
}
Done:
<-r.kill
}
func newRunner(ctx context.Context,numRunners int) *runner {
r := &runner{
WorkerPool: workerpool.New(numRunners),ctx: ctx,kill: make(chan struct{}),result: make(chan jobResult),}
go r.processResults()
return r
}
func (r *runner) do(j job) {
r.Submit(r.wrap(&j))
}
func (r *runner) getjobResults() []jobResult {
r.StopWait()
close(r.result)
r.kill <- struct{}{}
return r.results
}
func (r *runner) wrap(job *job) func() {
return func() {
job.result = make(chan jobResult)
go job.Run()
select {
case res := <-job.result:
r.result <- res
case <-r.ctx.Done():
fmt.Printf("Job '%s' should stop here\n",job.Name)
r.result <- jobResult{name: job.Name,Error: r.ctx.Err()}
}
}
}
type job struct {
Name string
Task func() jobResult
Context context.Context
result chan jobResult
stopped chan struct{}
done context.CancelFunc
}
func (j *job) Run() {
result := j.Task()
result.name = j.Name
j.result <- result
}
type jobResult struct {
name string
Error error
Data interface{}
}
,
它解决了,但不确定是否正确。
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
TokenEnhancerChain chain = new TokenEnhancerChain();
chain.setTokenEnhancers(Arrays.asList(customTokenEnhancer(),defaultAccessTokenConverter()));
endpoints.exceptionTranslator(new OAuth2ExceptionTranslator())
.tokenStore(tokenStore())
.tokenEnhancer(chain)
.authenticationManager(authenticationManager);
}
@Bean
public TokenStore tokenStore() {
return new RedisTokenStore(redisConnectionFactory);
}
@Bean
@Primary
public AuthorizationServerTokenServices tokenServices() {
TokenEnhancerChain chain = new TokenEnhancerChain();
chain.setTokenEnhancers(Arrays.asList(customTokenEnhancer(),defaultAccessTokenConverter()));
DefaultTokenServices tokenServices = new DefaultTokenServices();
tokenServices.setTokenEnhancer(chain);
tokenServices.setTokenStore(new JwtTokenStore(defaultAccessTokenConverter()));
tokenServices.setSupportRefreshToken(false);
return tokenServices;
}
如果有人有更好的主意,请发表评论。